better:尝试重构pfc

This commit is contained in:
SengokuCola
2025-04-08 00:23:08 +08:00
parent 0d7068acab
commit cc190ac2b9
6 changed files with 797 additions and 308 deletions

View File

@@ -5,6 +5,8 @@ from src.common.logger import get_module_logger
from src.common.database import db
from ..message.message_base import UserInfo
from ..config.config import global_config
from .chat_states import NotificationManager, create_new_message_notification, create_cold_chat_notification
from .message_storage import MessageStorage, MongoDBMessageStorage
logger = get_module_logger("chat_observer")
@@ -15,36 +17,40 @@ class ChatObserver:
_instances: Dict[str, 'ChatObserver'] = {}
@classmethod
def get_instance(cls, stream_id: str) -> 'ChatObserver':
def get_instance(cls, stream_id: str, message_storage: Optional[MessageStorage] = None) -> 'ChatObserver':
"""获取或创建观察器实例
Args:
stream_id: 聊天流ID
message_storage: 消息存储实现如果为None则使用MongoDB实现
Returns:
ChatObserver: 观察器实例
"""
if stream_id not in cls._instances:
cls._instances[stream_id] = cls(stream_id)
cls._instances[stream_id] = cls(stream_id, message_storage)
return cls._instances[stream_id]
def __init__(self, stream_id: str):
def __init__(self, stream_id: str, message_storage: Optional[MessageStorage] = None):
"""初始化观察器
Args:
stream_id: 聊天流ID
message_storage: 消息存储实现如果为None则使用MongoDB实现
"""
if stream_id in self._instances:
raise RuntimeError(f"ChatObserver for {stream_id} already exists. Use get_instance() instead.")
self.stream_id = stream_id
self.message_storage = message_storage or MongoDBMessageStorage()
self.last_user_speak_time: Optional[float] = None # 对方上次发言时间
self.last_bot_speak_time: Optional[float] = None # 机器人上次发言时间
self.last_check_time: float = time.time() # 上次查看聊天记录时间
self.last_message_read: Optional[str] = None # 最后读取的消息ID
self.last_message_time: Optional[float] = None # 最后一条消息的时间戳
self.waiting_start_time: Optional[float] = None # 等待开始时间
self.waiting_start_time: float = time.time() # 等待开始时间,初始化为当前时间
# 消息历史记录
self.message_history: List[Dict[str, Any]] = [] # 所有消息历史
@@ -56,8 +62,16 @@ class ChatObserver:
self._task: Optional[asyncio.Task] = None
self._update_event = asyncio.Event() # 触发更新的事件
self._update_complete = asyncio.Event() # 更新完成的事件
# 通知管理器
self.notification_manager = NotificationManager()
# 冷场检查配置
self.cold_chat_threshold: float = 60.0 # 60秒无消息判定为冷场
self.last_cold_chat_check: float = time.time()
self.is_cold_chat_state: bool = False
def check(self) -> bool:
async def check(self) -> bool:
"""检查距离上一次观察之后是否有了新消息
Returns:
@@ -65,13 +79,10 @@ class ChatObserver:
"""
logger.debug(f"检查距离上一次观察之后是否有了新消息: {self.last_check_time}")
query = {
"chat_id": self.stream_id,
"time": {"$gt": self.last_check_time}
}
# 只需要查询是否存在,不需要获取具体消息
new_message_exists = db.messages.find_one(query) is not None
new_message_exists = await self.message_storage.has_new_messages(
self.stream_id,
self.last_check_time
)
if new_message_exists:
logger.debug("发现新消息")
@@ -79,27 +90,8 @@ class ChatObserver:
return new_message_exists
def get_new_message(self) -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]]]:
"""获取上一次观察的时间点后的新消息,插入到历史记录中,并返回新消息和历史记录两个对象"""
messages = self.get_message_history(self.last_check_time)
for message in messages:
self._add_message_to_history(message)
return messages, self.message_history
def new_message_after(self, time_point: float) -> bool:
"""判断是否在指定时间点后有新消息
Args:
time_point: 时间戳
Returns:
bool: 是否有新消息
"""
logger.debug(f"判断是否在指定时间点后有新消息: {self.last_message_time} > {time_point}")
return self.last_message_time is None or self.last_message_time > time_point
def _add_message_to_history(self, message: Dict[str, Any]):
"""添加消息到历史记录
async def _add_message_to_history(self, message: Dict[str, Any]):
"""添加消息到历史记录并发送通知
Args:
message: 消息数据
@@ -116,6 +108,75 @@ class ChatObserver:
else:
self.last_user_speak_time = message["time"]
# 发送新消息通知
notification = create_new_message_notification(
sender="chat_observer",
target="pfc",
message=message
)
await self.notification_manager.send_notification(notification)
# 检查并更新冷场状态
await self._check_cold_chat()
async def _check_cold_chat(self):
"""检查是否处于冷场状态并发送通知"""
current_time = time.time()
# 每10秒检查一次冷场状态
if current_time - self.last_cold_chat_check < 10:
return
self.last_cold_chat_check = current_time
# 判断是否冷场
is_cold = False
if self.last_message_time is None:
is_cold = True
else:
is_cold = (current_time - self.last_message_time) > self.cold_chat_threshold
# 如果冷场状态发生变化,发送通知
if is_cold != self.is_cold_chat_state:
self.is_cold_chat_state = is_cold
notification = create_cold_chat_notification(
sender="chat_observer",
target="pfc",
is_cold=is_cold
)
await self.notification_manager.send_notification(notification)
async def get_new_message(self) -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]]]:
"""获取上一次观察的时间点后的新消息,插入到历史记录中,并返回新消息和历史记录两个对象"""
messages = await self.message_storage.get_messages_after(
self.stream_id,
self.last_message_read
)
for message in messages:
await self._add_message_to_history(message)
return messages, self.message_history
def new_message_after(self, time_point: float) -> bool:
"""判断是否在指定时间点后有新消息
Args:
time_point: 时间戳
Returns:
bool: 是否有新消息
"""
if time_point is None:
logger.warning("time_point 为 None返回 False")
return False
if self.last_message_time is None:
logger.debug("没有最后消息时间,返回 False")
return False
has_new = self.last_message_time > time_point
logger.debug(f"判断是否在指定时间点后有新消息: {self.last_message_time} > {time_point} = {has_new}")
return has_new
def get_message_history(
self,
start_time: Optional[float] = None,
@@ -159,15 +220,9 @@ class ChatObserver:
Returns:
List[Dict[str, Any]]: 新消息列表
"""
query = {"chat_id": self.stream_id}
if self.last_message_read:
# 获取ID大于last_message_read的消息
last_message = db.messages.find_one({"message_id": self.last_message_read})
if last_message:
query["time"] = {"$gt": last_message["time"]}
new_messages = list(
db.messages.find(query).sort("time", 1)
new_messages = await self.message_storage.get_messages_after(
self.stream_id,
self.last_message_read
)
if new_messages:
@@ -184,30 +239,24 @@ class ChatObserver:
Returns:
List[Dict[str, Any]]: 最多5条消息
"""
query = {
"chat_id": self.stream_id,
"time": {"$lt": time_point}
}
new_messages = list(
db.messages.find(query).sort("time", -1).limit(5) # 倒序获取5条
new_messages = await self.message_storage.get_messages_before(
self.stream_id,
time_point
)
# 将消息按时间正序排列
new_messages.reverse()
if new_messages:
self.last_message_read = new_messages[-1]["message_id"]
return new_messages
'''主要观察循环'''
async def _update_loop(self):
"""更新循环"""
try:
start_time = time.time()
messages = await self._fetch_new_messages_before(start_time)
for message in messages:
self._add_message_to_history(message)
await self._add_message_to_history(message)
except Exception as e:
logger.error(f"缓冲消息出错: {e}")
@@ -228,7 +277,7 @@ class ChatObserver:
if new_messages:
# 处理新消息
for message in new_messages:
self._add_message_to_history(message)
await self._add_message_to_history(message)
# 设置完成事件
self._update_complete.set()