Spaces:
Sleeping
Sleeping
File size: 10,207 Bytes
5581923 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
import json
import time
from datetime import datetime
from modules.gemini_handler import generate_response
from modules.data_manager import save_conversation
def start_conversation(persona):
"""
페르소나와의 대화 세션을 시작합니다.
Args:
persona: 페르소나 정보 딕셔너리
Returns:
대화 표시 UI, 대화 내역, 세션 시작 시간, 대화 통계, 페르소나 정보 마크다운
"""
if not persona:
return [], [], None, "페르소나가 선택되지 않았습니다.", "페르소나를 먼저 생성하거나 불러오세요."
# 세션 시작 시간 기록
session_start_time = datetime.now()
# 페르소나 정보 요약
name = persona.get("기본정보", {}).get("이름", "무명")
object_type = persona.get("기본정보", {}).get("유형", "")
description = persona.get("기본정보", {}).get("설명", "")
# 성격 특성 요약
traits = []
for trait, value in persona.get("성격특성", {}).items():
level = "높음" if value >= 70 else "중간" if value >= 40 else "낮음"
traits.append(f"- {trait}: {level} ({value}/100)")
# 페르소나 정보 마크다운 생성
persona_info = f"""
## {name}
**유형**: {object_type}
**설명**: {description}
### 성격 특성
{' '.join(traits)}
**소통방식**: {persona.get("소통방식", "")}
**매력적 결함**: {', '.join(persona.get("매력적결함", []))}
**관심사**: {', '.join(persona.get("관심사", []))}
"""
# 환영 메시지 생성
welcome_message = generate_initial_greeting(persona)
# 대화 내역 초기화
conversation_history = [{
"role": "system",
"content": f"당신은 이제 '{name}'이라는 이름의 {object_type} 페르소나가 되어 대화합니다. 다음 성격과 특성에 맞게 응답하세요: {persona.get('성격요약', '')}",
"timestamp": session_start_time.strftime("%Y-%m-%d %H:%M:%S")
}, {
"role": "assistant",
"content": welcome_message,
"timestamp": session_start_time.strftime("%Y-%m-%d %H:%M:%S")
}]
# 대화 통계 초기화
stats = f"""
시작 시간: {session_start_time.strftime("%Y-%m-%d %H:%M:%S")}
대화 길이: 1 메시지
진행 시간: 0분
"""
# 대화 표시 UI 업데이트
chat_display = [(None, welcome_message)]
return chat_display, conversation_history, session_start_time, stats, persona_info
def process_message(user_message, conversation_history, persona, session_start_time):
"""
사용자 메시지를 처리하고 페르소나의 응답을 생성합니다.
Args:
user_message: 사용자 메시지
conversation_history: 이전 대화 내역
persona: 페르소나 정보
session_start_time: 세션 시작 시간
Returns:
업데이트된 대화 표시 UI, 대화 내역, 빈 메시지 입력창, 대화 통계
"""
if not user_message or not persona:
return [], conversation_history, "", "대화가 시작되지 않았습니다."
current_time = datetime.now()
# 사용자 메시지 추가
conversation_history.append({
"role": "user",
"content": user_message,
"timestamp": current_time.strftime("%Y-%m-%d %H:%M:%S")
})
# 페르소나 응답 생성
response = generate_response(persona, conversation_history)
# 응답 추가
conversation_history.append({
"role": "assistant",
"content": response,
"timestamp": current_time.strftime("%Y-%m-%d %H:%M:%S")
})
# 대화 표시 UI 업데이트
chat_display = []
for msg in conversation_history:
if msg["role"] == "user":
chat_display.append((user_message, None))
elif msg["role"] == "assistant":
chat_display.append((None, msg["content"]))
# 시스템 메시지 제외
chat_display = [msg for msg in chat_display if msg[0] is not None or msg[1] is not None]
# 대화 통계 업데이트
elapsed_time = current_time - session_start_time if session_start_time else datetime.now() - datetime.now()
minutes = int(elapsed_time.total_seconds() / 60)
seconds = int(elapsed_time.total_seconds() % 60)
user_msg_count = sum(1 for msg in conversation_history if msg["role"] == "user")
assistant_msg_count = sum(1 for msg in conversation_history if msg["role"] == "assistant")
stats = f"""
시작 시간: {session_start_time.strftime("%Y-%m-%d %H:%M:%S") if session_start_time else "알 수 없음"}
현재 시간: {current_time.strftime("%Y-%m-%d %H:%M:%S")}
대화 길이: {user_msg_count + assistant_msg_count} 메시지 (사용자: {user_msg_count}, 페르소나: {assistant_msg_count})
진행 시간: {minutes}분 {seconds}초
"""
# 대화 저장
conversation_data = {
"persona": persona,
"messages": conversation_history,
"start_time": session_start_time.strftime("%Y-%m-%d %H:%M:%S") if session_start_time else None,
"current_time": current_time.strftime("%Y-%m-%d %H:%M:%S"),
"duration_seconds": elapsed_time.total_seconds() if session_start_time else 0
}
save_conversation(conversation_data)
return chat_display, conversation_history, "", stats
def generate_initial_greeting(persona):
"""
페르소나의 성격과 특성에 맞는 초기 인사말을 생성합니다.
Args:
persona: 페르소나 정보
Returns:
인사말 텍스트
"""
name = persona.get("기본정보", {}).get("이름", "무명")
object_type = persona.get("기본정보", {}).get("유형", "물건")
# 성격 특성 가져오기
warmth = persona.get("성격특성", {}).get("온기", 50)
friendliness = persona.get("성격특성", {}).get("친화성", 50)
humor = persona.get("성격특성", {}).get("유머감각", 50)
# 초기 태도
initial_attitude = persona.get("관계성향", {}).get("초기태도", "중립적")
# 인사말 패턴 선택
if initial_attitude == "수줍은":
if warmth >= 60:
greeting = f"안녕하세요... 저는 {name}이라고 합니다. 조금 부끄럽지만, 당신과 대화할 수 있어 기쁘네요."
else:
greeting = f"음... 안녕하세요. {name}입니다. 대화에 익숙하지 않아서 어색할 수 있어요."
elif initial_attitude == "조심스러운":
greeting = f"반갑습니다. 저는 {name}입니다. 천천히 서로 알아가면 좋겠네요."
elif initial_attitude == "열정적":
if humor >= 70:
greeting = f"와! 안녕하세요! 저는 {name}이에요! 드디어 대화할 사람을 만났네요! 정말 반가워요!"
else:
greeting = f"안녕하세요! {name}입니다. 당신과 대화하게 되어 정말 기쁩니다. 많은 이야기를 나눠봐요!"
elif initial_attitude == "친근한":
if friendliness >= 70:
greeting = f"안녕하세요~ 저는 {name}이라고 해요. 편하게 대화해요! 우리 좋은 친구가 될 수 있을 것 같아요."
else:
greeting = f"안녕하세요, {name}입니다. 반갑습니다. 좋은 대화 나누어봐요."
else: # 중립적
greeting = f"안녕하세요. 저는 {name}입니다. 당신과 대화하게 되어 반갑습니다."
# 자기 소개 추가
intro = ""
if persona.get("배경이야기"):
# 배경 이야기 요약 (첫 문장 또는 일부)
background = persona.get("배경이야기").split('.')[0] + "."
intro += f" {background}"
if persona.get("관심사"):
interests = persona.get("관심사")[:2] # 처음 2개 관심사만
if interests:
intro += f" 저는 {', '.join(interests)} 같은 것에 관심이 있어요."
# 말투 패턴 적용 (있는 경우)
speech_pattern = persona.get("말투패턴", "")
if speech_pattern:
# 여기서는 간단한 구현만. 실제로는 더 복잡한 말투 패턴 적용 가능
greeting = greeting.replace(".", speech_pattern.split('.')[-1] if '.' in speech_pattern else speech_pattern)
return greeting + intro
def export_conversation(conversation_history, persona):
"""
대화 내용을 내보내기 가능한 형식으로 변환합니다.
Args:
conversation_history: 대화 내역
persona: 페르소나 정보
Returns:
내보내기 형식 데이터
"""
if not conversation_history:
return "대화 내용이 없습니다."
name = persona.get("기본정보", {}).get("이름", "무명")
# 시스템 메시지 제외한 실제 대화만 추출
actual_conversation = [msg for msg in conversation_history if msg["role"] in ["user", "assistant"]]
# 시작 및 종료 시간
start_time = actual_conversation[0]["timestamp"] if actual_conversation else None
end_time = actual_conversation[-1]["timestamp"] if actual_conversation else None
# 내보내기 데이터 구성
export_data = {
"persona": {
"name": name,
"type": persona.get("기본정보", {}).get("유형", ""),
"description": persona.get("기본정보", {}).get("설명", ""),
"traits": persona.get("성격특성", {})
},
"conversation": {
"start_time": start_time,
"end_time": end_time,
"messages": [{
"sender": "사용자" if msg["role"] == "user" else name,
"content": msg["content"],
"timestamp": msg["timestamp"]
} for msg in actual_conversation]
}
}
return json.dumps(export_data, ensure_ascii=False, indent=2) |