refactor(schedule): 重构睡眠系统为状态机模型

将原有的睡眠、失眠、唤醒等分散的布尔标记逻辑重构为一个统一的睡眠状态机(SleepState),以提高代码的可读性、可维护性和可扩展性。

主要变更:
- 引入 `SleepState` 枚举,包含 `AWAKE`, `INSOMNIA`, `PREPARING_SLEEP`, `SLEEPING`, `WOKEN_UP` 状态。
- 在 `ScheduleManager` 中实现 `_update_sleep_state` 作为核心状态机,统一管理所有状态转换。
- 将原有的失眠判断逻辑从 `WakeUpManager` 移至 `ScheduleManager` 的状态机内部,与弹性睡眠决策合并,简化了模块职责。
- `heartFC_chat.py` 中的聊天循环现在直接查询 `ScheduleManager` 的当前状态,而不是处理多个独立的布尔值,使逻辑更清晰。
- 删除了 `WakeUpManager` 中与失眠相关的配置和方法,因为它现在由 `ScheduleManager` 统一管理。
- 删除了配置中已废弃的 `enable_is_sleep` 选项。
This commit is contained in:
minecraft1024a
2025-08-29 17:40:22 +08:00
parent 01455156a7
commit 41565eb144
4 changed files with 150 additions and 183 deletions

View File

@@ -8,7 +8,7 @@ from src.config.config import global_config
from src.person_info.relationship_builder_manager import relationship_builder_manager
from src.chat.express.expression_learner import expression_learner_manager
from src.plugin_system.base.component_types import ChatMode
from src.schedule.schedule_manager import schedule_manager
from src.schedule.schedule_manager import schedule_manager, SleepState
from src.plugin_system.apis import message_api
from .hfc_context import HfcContext
@@ -196,30 +196,14 @@ class HeartFChatting:
- FOCUS模式直接处理所有消息并检查退出条件
- NORMAL模式检查进入FOCUS模式的条件并通过normal_mode_handler处理消息
"""
is_sleeping = schedule_manager.is_sleeping(self.wakeup_manager)
# --- 失眠状态管理 ---
if self.context.is_in_insomnia and time.time() > self.context.insomnia_end_time:
# 失眠状态结束
self.context.is_in_insomnia = False
await self.proactive_thinker.trigger_goodnight_thinking()
if is_sleeping and not self.context.was_sleeping:
# 刚刚进入睡眠状态,进行一次入睡检查
if self.wakeup_manager and self.wakeup_manager.check_for_insomnia():
# 触发失眠
self.context.is_in_insomnia = True
duration = global_config.sleep_system.insomnia_duration_minutes * 60
self.context.insomnia_end_time = time.time() + duration
# 判断失眠原因并触发思考
reason = "random"
if self.context.sleep_pressure < global_config.sleep_system.sleep_pressure_threshold:
reason = "low_pressure"
await self.proactive_thinker.trigger_insomnia_thinking(reason)
# --- 核心状态更新 ---
await schedule_manager._update_sleep_state(self.wakeup_manager)
current_sleep_state = schedule_manager.get_current_sleep_state()
is_sleeping = current_sleep_state == SleepState.SLEEPING
is_in_insomnia = current_sleep_state == SleepState.INSOMNIA
# 核心修复:在睡眠模式(包括失眠)下获取消息时,不过滤命令消息,以确保@消息能被接收
filter_command_flag = not is_sleeping
filter_command_flag = not (is_sleeping or is_in_insomnia)
recent_messages = message_api.get_messages_by_time_in_chat(
chat_id=self.context.stream_id,
@@ -239,16 +223,17 @@ class HeartFChatting:
self.context.last_read_time = time.time()
# 处理唤醒度逻辑
if is_sleeping:
if current_sleep_state in [SleepState.SLEEPING, SleepState.PREPARING_SLEEP, SleepState.INSOMNIA]:
self._handle_wakeup_messages(recent_messages)
# 再次检查睡眠状态因为_handle_wakeup_messages可能会触发唤醒
current_is_sleeping = schedule_manager.is_sleeping(self.wakeup_manager)
if not self.context.is_in_insomnia and current_is_sleeping:
# 仍然在睡眠,跳过本轮的消息处理
# 再次获取最新状态,因为 handle_wakeup 可能导致状态变为 WOKEN_UP
current_sleep_state = schedule_manager.get_current_sleep_state()
if current_sleep_state == SleepState.SLEEPING:
# 只有在纯粹的 SLEEPING 状态下才跳过消息处理
return has_new_messages
else:
# 从睡眠中被唤醒,需要继续处理本轮消息
if current_sleep_state == SleepState.WOKEN_UP:
logger.info(f"{self.context.log_prefix} 从睡眠中被唤醒,将处理积压的消息。")
self.context.last_wakeup_time = time.time()