feat(chat): 为消息管理器添加睡眠与唤醒机制

将 `SleepManager` 和 `WakeUpManager` 集成到 `MessageManager` 中,以实现机器人的睡眠和唤醒功能。

在睡眠状态下,机器人将忽略常规消息,不进行处理。只有当接收到特定唤醒触发器(如私聊消息或在群聊中被@)时,机器人才能被唤醒并恢复正常的消息处理流程。

此机制旨在模拟更自然的用户行为,并在机器人非活跃时段减少不必要的打扰。
This commit is contained in:
minecraft1024a
2025-09-23 21:53:00 +08:00
parent ff72181649
commit 2414912c06
6 changed files with 820 additions and 1 deletions

View File

@@ -13,6 +13,8 @@ from src.common.data_models.database_data_model import DatabaseMessages
from src.common.data_models.message_manager_data_model import StreamContext, MessageManagerStats, StreamStats
from src.chat.chatter_manager import ChatterManager
from src.chat.planner_actions.action_manager import ChatterActionManager
from .sleep_manager.sleep_manager import SleepManager
from .sleep_manager.wakeup_manager import WakeUpManager
if TYPE_CHECKING:
from src.common.data_models.message_manager_data_model import StreamContext
@@ -36,6 +38,10 @@ class MessageManager:
self.action_manager = ChatterActionManager()
self.chatter_manager = ChatterManager(self.action_manager)
# 初始化睡眠和唤醒管理器
self.sleep_manager = SleepManager()
self.wakeup_manager = WakeUpManager(self.sleep_manager)
async def start(self):
"""启动消息管理器"""
if self.is_running:
@@ -44,6 +50,7 @@ class MessageManager:
self.is_running = True
self.manager_task = asyncio.create_task(self._manager_loop())
await self.wakeup_manager.start()
logger.info("消息管理器已启动")
async def stop(self):
@@ -61,6 +68,8 @@ class MessageManager:
# 停止管理器任务
if self.manager_task and not self.manager_task.done():
self.manager_task.cancel()
await self.wakeup_manager.stop()
logger.info("消息管理器已停止")
@@ -80,6 +89,9 @@ class MessageManager:
"""管理器主循环"""
while self.is_running:
try:
# 更新睡眠状态
await self.sleep_manager.update_sleep_state(self.wakeup_manager)
await self._check_all_streams()
await asyncio.sleep(self.check_interval)
except asyncio.CancelledError:
@@ -124,6 +136,28 @@ class MessageManager:
unread_messages = context.get_unread_messages()
if not unread_messages:
return
# --- 睡眠状态检查 ---
from .sleep_manager.sleep_state import SleepState
if self.sleep_manager.is_sleeping():
logger.info(f"Bot正在睡觉检查聊天流 {stream_id} 是否有唤醒触发器。")
was_woken_up = False
is_private = context.is_private_chat()
for message in unread_messages:
is_mentioned = message.is_mentioned or False
if is_private or is_mentioned:
if self.wakeup_manager.add_wakeup_value(is_private, is_mentioned):
was_woken_up = True
break # 一旦被吵醒,就跳出循环并处理消息
if not was_woken_up:
logger.debug(f"聊天流 {stream_id} 中没有唤醒触发器,保持消息未读状态。")
return # 退出,不处理消息
logger.info(f"Bot被聊天流 {stream_id} 中的消息吵醒,继续处理。")
# --- 睡眠状态检查结束 ---
logger.debug(f"开始处理聊天流 {stream_id}{len(unread_messages)} 条未读消息")
@@ -187,7 +221,7 @@ class MessageManager:
unread_count=len(context.get_unread_messages()),
history_count=len(context.history_messages),
last_check_time=context.last_check_time,
has_active_task=context.processing_task and not context.processing_task.done(),
has_active_task=bool(context.processing_task and not context.processing_task.done()),
)
def get_manager_stats(self) -> Dict[str, Any]: