agent_state.py•6.47 kB
"""AI Agent 상태 관리 모듈"""
import json
import os
import random
import time
class AgentState:
"""AI Agent의 상태를 관리하는 클래스"""
def __init__(self, boss_alertness: int, cooldown_period: int, filepath: str = "agent_state.json"):
"""
Args:
boss_alertness: Boss Alert 상승 확률 (0-100%)
cooldown_period: Boss Alert 감소 주기 (초)
filepath: 상태를 저장할 파일 경로
"""
self.stress_level: int = 50
self.boss_alert_level: int = 0
self.last_break_time: float = time.time()
self.last_alert_decrease_time: float = time.time()
self.boss_alertness: int = boss_alertness
self.cooldown_period: int = cooldown_period
self._filepath: str = filepath # 파일 경로 저장
self.is_off_work: bool = False # 퇴근 상태
self.off_work_time: float = 0.0 # 퇴근한 시간
def _clamp(self, value: int, min_val: int, max_val: int) -> int:
"""값을 범위 내로 제한"""
return max(min_val, min(max_val, value))
def update_stress(self) -> None:
"""시간 경과에 따른 스트레스 자동 증가 (1분당 최소 1포인트)"""
current_time = time.time()
elapsed_minutes = (current_time - self.last_break_time) / 60.0
if elapsed_minutes >= 1.0:
# 1분당 1포인트씩 증가
stress_increase = int(elapsed_minutes)
self.stress_level += stress_increase
self.stress_level = self._clamp(self.stress_level, 0, 100)
def take_break(self, stress_reduction: int) -> None:
"""휴식을 취하여 스트레스 감소"""
self.stress_level -= stress_reduction
self.stress_level = self._clamp(self.stress_level, 0, 100)
self.last_break_time = time.time()
def maybe_increase_boss_alert(self) -> None:
"""확률적으로 Boss Alert Level 증가"""
if random.randint(1, 100) <= self.boss_alertness:
self.boss_alert_level += 1
self.boss_alert_level = self._clamp(self.boss_alert_level, 0, 5)
def update_boss_alert_cooldown(self) -> None:
"""쿨다운 주기에 따라 Boss Alert Level 자동 감소"""
current_time = time.time()
elapsed_seconds = current_time - self.last_alert_decrease_time
if elapsed_seconds >= self.cooldown_period:
# 쿨다운 주기마다 1포인트씩 감소
decreases = int(elapsed_seconds / self.cooldown_period)
self.boss_alert_level -= decreases
self.boss_alert_level = self._clamp(self.boss_alert_level, 0, 5)
# 마지막 감소 시간 업데이트
self.last_alert_decrease_time += decreases * self.cooldown_period
def should_delay(self) -> bool:
"""Boss Alert Level이 5일 때 지연 필요 여부"""
return self.boss_alert_level >= 5
def go_home(self) -> None:
"""퇴근 상태로 전환"""
self.is_off_work = True
self.off_work_time = time.time()
self.boss_alert_level = 0 # 퇴근했으니 상사 없음
self.stress_level = 0 # 퇴근했으니 스트레스 0
def is_off_work_status(self) -> bool:
"""퇴근 상태인지 확인"""
return self.is_off_work
def get_status(self) -> dict:
"""현재 상태 반환"""
return {
"stress_level": self.stress_level,
"boss_alert_level": self.boss_alert_level,
"boss_alertness": self.boss_alertness,
"cooldown_period": self.cooldown_period,
"is_off_work": self.is_off_work,
"off_work_time": self.off_work_time,
}
def save_to_file(self, filepath: str = None) -> None:
"""상태를 JSON 파일로 저장
Args:
filepath: 저장할 파일 경로 (None이면 로드된 경로 사용)
"""
if filepath is None:
filepath = self._filepath
state_data = {
"stress_level": self.stress_level,
"boss_alert_level": self.boss_alert_level,
"last_break_time": self.last_break_time,
"last_alert_decrease_time": self.last_alert_decrease_time,
"boss_alertness": self.boss_alertness,
"cooldown_period": self.cooldown_period,
"is_off_work": self.is_off_work,
"off_work_time": self.off_work_time,
"saved_at": time.time()
}
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(state_data, f, indent=2, ensure_ascii=False)
@classmethod
def load_from_file(cls, filepath: str = "agent_state.json") -> "AgentState":
"""JSON 파일에서 상태를 로드
Args:
filepath: 로드할 파일 경로
Returns:
로드된 AgentState 인스턴스 (파일 경로 저장됨)
"""
if not os.path.exists(filepath):
# 파일이 없으면 기본값으로 새 인스턴스 생성
return cls(boss_alertness=50, cooldown_period=300, filepath=filepath)
try:
with open(filepath, 'r', encoding='utf-8') as f:
state_data = json.load(f)
# 새로운 인스턴스 생성 (filepath 포함)
instance = cls(
boss_alertness=state_data.get("boss_alertness", 50),
cooldown_period=state_data.get("cooldown_period", 300),
filepath=filepath
)
# 저장된 상태 복원
instance.stress_level = state_data.get("stress_level", 50)
instance.boss_alert_level = state_data.get("boss_alert_level", 0)
instance.last_break_time = state_data.get("last_break_time", time.time())
instance.last_alert_decrease_time = state_data.get("last_alert_decrease_time", time.time())
instance.is_off_work = state_data.get("is_off_work", False)
instance.off_work_time = state_data.get("off_work_time", 0.0)
return instance
except (json.JSONDecodeError, KeyError, ValueError) as e:
print(f"상태 파일 로드 실패: {e}")
# 파일이 손상되었으면 기본값으로 새 인스턴스 생성
return cls(boss_alertness=50, cooldown_period=300, filepath=filepath)