77import streamlit as st
88
99from utils .llm .chatbot import ChatBot
10+ from interface .app_pages .sidebar_components import (
11+ render_sidebar_data_source_selector ,
12+ render_sidebar_llm_selector ,
13+ render_sidebar_embedding_selector ,
14+ render_sidebar_db_selector ,
15+ render_sidebar_chatbot_session_controller ,
16+ )
17+ from interface .core .config import load_config
1018
1119
1220def initialize_session_state ():
1321 """세션 상태 초기화 함수
1422
1523 Streamlit의 session_state를 사용하여 앱의 상태를 유지합니다.
24+ LLM 설정을 sidebar의 llm_selector에서 선택한 값으로부터 가져옵니다.
1625 """
17- # 채팅 세션 시작 여부 플래그
18- if "chatbot_started" not in st .session_state :
19- st .session_state .chatbot_started = False
20- # 채팅 메시지 기록 저장
26+ # 채팅 메시지 기록 저장 (자동으로 시작)
2127 if "chatbot_messages" not in st .session_state :
2228 st .session_state .chatbot_messages = []
2329
30+ # LLM 공급자 확인 (현재 ChatBot은 OpenAI만 지원)
31+ llm_provider = (
32+ st .session_state .get ("LLM_PROVIDER" ) or os .getenv ("LLM_PROVIDER" ) or "openai"
33+ ).lower ()
34+
35+ if llm_provider != "openai" :
36+ st .error (
37+ f"⚠️ ChatBot은 현재 OpenAI만 지원합니다. 설정 > LLM에서 OpenAI 프로파일을 선택하거나 LLM_PROVIDER를 'openai'로 설정해주세요."
38+ )
39+ st .stop ()
40+
2441 # OpenAI API 키 확인
2542 openai_api_key = st .session_state .get ("OPEN_AI_KEY" ) or os .getenv ("OPEN_AI_KEY" )
2643
2744 if not openai_api_key :
2845 st .error (
29- "⚠️ OpenAI API 키가 설정되지 않았습니다. 설정 > LLM에서 OpenAI API 키를 입력해주세요 ."
46+ "⚠️ OpenAI API 키가 설정되지 않았습니다. 설정 > LLM에서 OpenAI API 키를 입력하거나, 사이드바에서 LLM 프로파일을 적용해주세요 ."
3047 )
3148 st .stop ()
3249
33- # ChatBot 인스턴스 생성 (OpenAI API 키 사용)
50+ # 사용할 모델명 가져오기 (llm_selector에서 설정한 값)
51+ model_name = (
52+ st .session_state .get ("OPEN_AI_LLM_MODEL" )
53+ or os .getenv ("OPEN_AI_LLM_MODEL" )
54+ or "gpt-4o-mini"
55+ )
56+
57+ # ChatBot 인스턴스 생성 또는 모델 업데이트
3458 if "chatbot_instance" not in st .session_state :
35- st .session_state .chatbot_instance = ChatBot (openai_api_key )
59+ st .session_state .chatbot_instance = ChatBot (
60+ openai_api_key , model_name = model_name
61+ )
62+ else :
63+ # 기존 인스턴스가 있는 경우, 모델이나 API 키가 변경되었는지 확인
64+ existing_bot = st .session_state .chatbot_instance
65+ if (
66+ existing_bot .model_name != model_name
67+ or existing_bot .openai_api_key != openai_api_key
68+ ):
69+ st .session_state .chatbot_instance = ChatBot (
70+ openai_api_key , model_name = model_name
71+ )
3672
3773
3874# 세션 상태 초기화 실행
@@ -50,101 +86,68 @@ def initialize_session_state():
5086 """
5187)
5288
53- # 사이드바 UI 구성
54- with st .sidebar :
55- st .markdown ("### 🤖 ChatBot 설정" )
56- st .divider ()
57-
58- # LLM 모델 선택 드롭다운
59- selected_model = st .selectbox (
60- "LLM 모델" ,
61- options = list (ChatBot .AVAILABLE_MODELS .keys ()),
62- format_func = lambda x : ChatBot .AVAILABLE_MODELS [x ],
63- key = "chatbot_model_select" ,
64- )
89+ # 설정 로드
90+ config = load_config ()
6591
66- # 선택된 모델이 변경되면 ChatBot 업데이트
67- if selected_model != st .session_state .chatbot_instance .model_name :
68- st .session_state .chatbot_instance .update_model (selected_model )
69- st .sidebar .success (
70- f"모델이 '{ ChatBot .AVAILABLE_MODELS [selected_model ]} '로 변경되었습니다."
71- )
92+ # 사이드바 UI 구성 (lang2sql.py와 동일한 구조)
93+ render_sidebar_data_source_selector (config )
94+ st .sidebar .divider ()
95+ render_sidebar_llm_selector ()
96+ st .sidebar .divider ()
97+ render_sidebar_embedding_selector ()
98+ st .sidebar .divider ()
99+ render_sidebar_db_selector ()
100+ st .sidebar .divider ()
72101
102+ # ChatBot 전용 설정
103+ with st .sidebar :
104+ st .markdown ("### 🤖 ChatBot 설정" )
73105 st .divider ()
74-
75- # 채팅 세션 ID 입력 (대화 기록을 구분하는 용도)
76- thread_id = st .text_input (
77- "세션 ID" ,
78- value = "default" ,
79- key = "chatbot_thread_id" ,
80- help = "대화 기록을 구분하는 고유 ID입니다." ,
81- )
82-
83- # 채팅 세션 시작/종료 버튼
84- if not st .session_state .chatbot_started :
85- # 세션이 시작되지 않았을 때: 시작 버튼 표시
86- if st .button ("대화 시작" , use_container_width = True , type = "primary" ):
87- st .session_state .chatbot_started = True
88- st .session_state .chatbot_messages = []
89- st .rerun ()
90- else :
91- # 세션이 시작되었을 때: 종료 버튼 표시
92- if st .button ("대화 종료" , use_container_width = True ):
93- st .session_state .chatbot_started = False
94- st .rerun ()
95-
96- st .divider ()
97-
98- # 세션 히스토리를 JSON 형식으로 표시 (접힌 상태)
99- with st .expander ("대화 기록 (JSON)" , expanded = False ):
100- st .json (st .session_state .chatbot_messages )
101-
102- # 채팅 세션이 시작된 경우에만 채팅 인터페이스 표시
103- if st .session_state .chatbot_started :
104- # 첫 메시지가 없으면 환영 메시지 추가
105- if not st .session_state .chatbot_messages :
106- hello_message = "안녕하세요! 무엇을 도와드릴까요? 🤖"
107- st .session_state .chatbot_messages = [
108- {"role" : "assistant" , "content" : hello_message }
109- ]
110-
111- # 저장된 모든 메시지를 순서대로 표시
112- for message in st .session_state .chatbot_messages :
113- with st .chat_message (message ["role" ]):
114- st .markdown (message ["content" ])
115-
116- # 사용자 입력 처리
117- if prompt := st .chat_input ("메시지를 입력하세요" ):
118- # 사용자 메시지를 기록에 추가
119- st .session_state .chatbot_messages .append ({"role" : "user" , "content" : prompt })
120- with st .chat_message ("user" ):
121- st .markdown (prompt )
122-
123- # AI 응답 생성 및 표시
124- with st .chat_message ("assistant" ):
125- try :
126- # ChatBot을 통해 응답 생성
127- response = st .session_state .chatbot_instance .chat (prompt , thread_id )
128-
129- # 응답 내용 추출
130- response_content = response ["messages" ][- 1 ].content
131-
132- # 스트리밍 방식으로 응답 표시 (타이핑 효과)
133- response_str = ""
134- response_container = st .empty ()
135- for token in response_content :
136- response_str += token
137- response_container .markdown (response_str )
138-
139- # AI 응답을 기록에 추가
140- st .session_state .chatbot_messages .append (
141- {"role" : "assistant" , "content" : response_content }
142- )
143- except Exception as e :
144- error_msg = f"오류가 발생했습니다: { str (e )} "
145- st .error (error_msg )
146- st .session_state .chatbot_messages .append (
147- {"role" : "assistant" , "content" : error_msg }
148- )
149- else :
150- st .info ("👈 왼쪽 사이드바에서 '대화 시작' 버튼을 눌러 ChatBot과 대화를 시작하세요!" )
106+ thread_id = render_sidebar_chatbot_session_controller ()
107+
108+
109+ # 첫 메시지가 없으면 환영 메시지 추가
110+ if not st .session_state .chatbot_messages :
111+ hello_message = "안녕하세요! 무엇을 도와드릴까요? 🤖"
112+ st .session_state .chatbot_messages = [
113+ {"role" : "assistant" , "content" : hello_message }
114+ ]
115+
116+ # 저장된 모든 메시지를 순서대로 표시
117+ for message in st .session_state .chatbot_messages :
118+ with st .chat_message (message ["role" ]):
119+ st .markdown (message ["content" ])
120+
121+ # 사용자 입력 처리
122+ if prompt := st .chat_input ("메시지를 입력하세요" ):
123+ # 사용자 메시지를 기록에 추가
124+ st .session_state .chatbot_messages .append ({"role" : "user" , "content" : prompt })
125+ with st .chat_message ("user" ):
126+ st .markdown (prompt )
127+
128+ # AI 응답 생성 및 표시
129+ with st .chat_message ("assistant" ):
130+ try :
131+ # ChatBot을 통해 응답 생성
132+ response = st .session_state .chatbot_instance .chat (prompt , thread_id )
133+
134+ # 응답 내용 추출
135+ response_content = response ["messages" ][- 1 ].content
136+
137+ # 모델 정보 표시
138+ model_name = st .session_state .chatbot_instance .model_name
139+ st .caption (f"🤖 모델: { model_name } " )
140+
141+ # 응답 표시
142+ st .markdown (response_content )
143+
144+ # AI 응답을 기록에 추가
145+ st .session_state .chatbot_messages .append (
146+ {"role" : "assistant" , "content" : response_content }
147+ )
148+ except Exception as e :
149+ error_msg = f"오류가 발생했습니다: { str (e )} "
150+ st .error (error_msg )
151+ st .session_state .chatbot_messages .append (
152+ {"role" : "assistant" , "content" : error_msg }
153+ )
0 commit comments