diff --git a/src/plugins/PFC/action_planner.py b/src/plugins/PFC/action_planner.py index 4e39483bf..e29d8c4fc 100644 --- a/src/plugins/PFC/action_planner.py +++ b/src/plugins/PFC/action_planner.py @@ -8,6 +8,7 @@ from .pfc_utils import get_items_from_json from src.individuality.individuality import Individuality from .observation_info import ObservationInfo from .conversation_info import ConversationInfo +from src.plugins.utils.chat_message_builder import build_readable_messages pfc_action_log_config = LogConfig( console_format=PFC_ACTION_PLANNER_STYLE_CONFIG["console_format"], @@ -132,12 +133,7 @@ class ActionPlanner: chat_history_text = "" try: if hasattr(observation_info, "chat_history") and observation_info.chat_history: - chat_history_list = observation_info.chat_history[-20:] - for msg in chat_history_list: - if isinstance(msg, dict) and "detailed_plain_text" in msg: - chat_history_text += f"{msg.get('detailed_plain_text', '')}\n" - elif isinstance(msg, str): - chat_history_text += f"{msg}\n" + chat_history_text = observation_info.chat_history_str if not chat_history_text: # 如果历史记录是空列表 chat_history_text = "还没有聊天记录。\n" else: @@ -146,12 +142,16 @@ class ActionPlanner: if hasattr(observation_info, "new_messages_count") and observation_info.new_messages_count > 0: if hasattr(observation_info, "unprocessed_messages") and observation_info.unprocessed_messages: new_messages_list = observation_info.unprocessed_messages - chat_history_text += f"--- 以下是 {observation_info.new_messages_count} 条新消息 ---\n" - for msg in new_messages_list: - if isinstance(msg, dict) and "detailed_plain_text" in msg: - chat_history_text += f"{msg.get('detailed_plain_text', '')}\n" - elif isinstance(msg, str): - chat_history_text += f"{msg}\n" + new_messages_str = await build_readable_messages( + new_messages_list, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, + ) + chat_history_text += ( + f"\n--- 以下是 {observation_info.new_messages_count} 条新消息 ---\n{new_messages_str}" + ) # 清理消息应该由调用者或 observation_info 内部逻辑处理,这里不再调用 clear # if hasattr(observation_info, 'clear_unprocessed_messages'): # observation_info.clear_unprocessed_messages() diff --git a/src/plugins/PFC/conversation.py b/src/plugins/PFC/conversation.py index c56cc3e17..6bcb53fe2 100644 --- a/src/plugins/PFC/conversation.py +++ b/src/plugins/PFC/conversation.py @@ -3,7 +3,7 @@ import asyncio import datetime # from .message_storage import MongoDBMessageStorage -from src.plugins.utils.chat_message_builder import get_raw_msg_before_timestamp_with_chat +from src.plugins.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat # from ...config.config import global_config from typing import Dict, Any @@ -83,9 +83,17 @@ class Conversation: timestamp=time.time(), limit=30, # 加载最近30条作为初始上下文,可以调整 ) + chat_talking_prompt = await build_readable_messages( + initial_messages, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, + ) if initial_messages: # 将加载的消息填充到 ObservationInfo 的 chat_history self.observation_info.chat_history = initial_messages + self.observation_info.chat_history_str = chat_talking_prompt + "\n" self.observation_info.chat_history_count = len(initial_messages) # 更新 ObservationInfo 中的时间戳等信息 @@ -163,7 +171,7 @@ class Conversation: if hasattr(self.observation_info, "clear_unprocessed_messages"): # 确保 clear_unprocessed_messages 方法存在 logger.debug(f"准备执行 direct_reply,清理 {initial_new_message_count} 条规划时已知的新消息。") - self.observation_info.clear_unprocessed_messages() + await self.observation_info.clear_unprocessed_messages() # 手动重置计数器,确保状态一致性(理想情况下 clear 方法会做这个) if hasattr(self.observation_info, "new_messages_count"): self.observation_info.new_messages_count = 0 @@ -273,6 +281,7 @@ class Conversation: reply=self.generated_reply, goal=current_goal_str, chat_history=observation_info.chat_history, + chat_history_str=observation_info.chat_history_str, retry_count=reply_attempt_count - 1, # 传递当前尝试次数(从0开始计数) ) logger.info( @@ -442,7 +451,6 @@ class Conversation: # 发送消息 await self.direct_sender.send_message(chat_stream=self.chat_stream, content=reply_content) - logger.info(f"消息已发送: {reply_content}") # 可以在发送后加个日志确认 # 原有的触发更新和等待代码 self.chat_observer.trigger_update() diff --git a/src/plugins/PFC/observation_info.py b/src/plugins/PFC/observation_info.py index 4cb6aaaa8..072b1fb6f 100644 --- a/src/plugins/PFC/observation_info.py +++ b/src/plugins/PFC/observation_info.py @@ -7,6 +7,7 @@ from dataclasses import dataclass, field from src.common.logger import get_module_logger from .chat_observer import ChatObserver from .chat_states import NotificationHandler, NotificationType +from src.plugins.utils.chat_message_builder import build_readable_messages logger = get_module_logger("observation_info") @@ -97,6 +98,7 @@ class ObservationInfo: # data_list chat_history: List[str] = field(default_factory=list) + chat_history_str: str = "" unprocessed_messages: List[Dict[str, Any]] = field(default_factory=list) active_users: Set[str] = field(default_factory=set) @@ -223,11 +225,18 @@ class ObservationInfo: return None return time.time() - self.last_bot_speak_time - def clear_unprocessed_messages(self): + async def clear_unprocessed_messages(self): """清空未处理消息列表""" # 将未处理消息添加到历史记录中 for message in self.unprocessed_messages: self.chat_history.append(message) + self.chat_history_str = await build_readable_messages( + self.chat_history[-20:] if len(self.chat_history) > 20 else self.chat_history, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, + ) # 清空未处理消息列表 self.has_unread_messages = False self.unprocessed_messages.clear() diff --git a/src/plugins/PFC/pfc.py b/src/plugins/PFC/pfc.py index ac8338626..5a70d02f3 100644 --- a/src/plugins/PFC/pfc.py +++ b/src/plugins/PFC/pfc.py @@ -19,6 +19,7 @@ from src.individuality.individuality import Individuality from .conversation_info import ConversationInfo from .observation_info import ObservationInfo import time +from src.plugins.utils.chat_message_builder import build_readable_messages if TYPE_CHECKING: pass @@ -80,19 +81,20 @@ class GoalAnalyzer: goals_str = f"目标:{goal},产生该对话目标的原因:{reasoning}\n" # 获取聊天历史记录 - chat_history_list = observation_info.chat_history - chat_history_text = "" - for msg in chat_history_list: - chat_history_text += f"{msg}\n" + chat_history_text = observation_info.chat_history if observation_info.new_messages_count > 0: new_messages_list = observation_info.unprocessed_messages + new_messages_str = await build_readable_messages( + new_messages_list, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, + ) + chat_history_text += f"\n--- 以下是 {observation_info.new_messages_count} 条新消息 ---\n{new_messages_str}" - chat_history_text += f"有{observation_info.new_messages_count}条新消息:\n" - for msg in new_messages_list: - chat_history_text += f"{msg}\n" - - observation_info.clear_unprocessed_messages() + # await observation_info.clear_unprocessed_messages() identity_details_only = self.identity_detail_info identity_addon = "" diff --git a/src/plugins/PFC/reply_checker.py b/src/plugins/PFC/reply_checker.py index 1f6f91ddf..26b20875c 100644 --- a/src/plugins/PFC/reply_checker.py +++ b/src/plugins/PFC/reply_checker.py @@ -1,5 +1,4 @@ import json -import datetime from typing import Tuple, List, Dict, Any from src.common.logger import get_module_logger from ..models.utils_model import LLMRequest @@ -22,7 +21,7 @@ class ReplyChecker: self.max_retries = 3 # 最大重试次数 async def check( - self, reply: str, goal: str, chat_history: List[Dict[str, Any]], retry_count: int = 0 + self, reply: str, goal: str, chat_history: List[Dict[str, Any]], chat_history_text: str, retry_count: int = 0 ) -> Tuple[bool, str, bool]: """检查生成的回复是否合适 @@ -36,7 +35,6 @@ class ReplyChecker: """ # 不再从 observer 获取,直接使用传入的 chat_history # messages = self.chat_observer.get_cached_messages(limit=20) - chat_history_text = "" try: # 筛选出最近由 Bot 自己发送的消息 bot_messages = [] @@ -82,14 +80,6 @@ class ReplyChecker: logger.error(f"检查回复时出错: 类型={type(e)}, 值={e}") logger.error(traceback.format_exc()) # 打印详细的回溯信息 - for msg in chat_history[-20:]: - time_str = datetime.datetime.fromtimestamp(msg["time"]).strftime("%H:%M:%S") - user_info = UserInfo.from_dict(msg.get("user_info", {})) - sender = user_info.user_nickname or f"用户{user_info.user_id}" - if sender == self.name: - sender = "你说" - chat_history_text += f"{time_str},{sender}:{msg.get('processed_plain_text', '')}\n" - prompt = f"""请检查以下回复或消息是否合适: 当前对话目标:{goal} diff --git a/src/plugins/PFC/reply_generator.py b/src/plugins/PFC/reply_generator.py index fe9dab6f5..65afbf64d 100644 --- a/src/plugins/PFC/reply_generator.py +++ b/src/plugins/PFC/reply_generator.py @@ -7,6 +7,7 @@ from .reply_checker import ReplyChecker from src.individuality.individuality import Individuality from .observation_info import ObservationInfo from .conversation_info import ConversationInfo +from src.plugins.utils.chat_message_builder import build_readable_messages logger = get_module_logger("reply_generator") @@ -68,23 +69,19 @@ class ReplyGenerator: goals_str = f"目标:{goal},产生该对话目标的原因:{reasoning}\n" # 获取聊天历史记录 - chat_history_list = ( - observation_info.chat_history[-20:] - if len(observation_info.chat_history) >= 20 - else observation_info.chat_history - ) - chat_history_text = "" - for msg in chat_history_list: - chat_history_text += f"{msg.get('detailed_plain_text', '')}\n" + chat_history_text = observation_info.chat_history_str if observation_info.new_messages_count > 0: new_messages_list = observation_info.unprocessed_messages - - chat_history_text += f"有{observation_info.new_messages_count}条新消息:\n" - for msg in new_messages_list: - chat_history_text += f"{msg.get('detailed_plain_text', '')}\n" - - observation_info.clear_unprocessed_messages() + new_messages_str = await build_readable_messages( + new_messages_list, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="relative", + read_mark=0.0, + ) + chat_history_text += f"\n--- 以下是 {observation_info.new_messages_count} 条新消息 ---\n{new_messages_str}" + # await observation_info.clear_unprocessed_messages() identity_details_only = self.identity_detail_info identity_addon = "" @@ -173,7 +170,7 @@ class ReplyGenerator: return "抱歉,我现在有点混乱,让我重新思考一下..." async def check_reply( - self, reply: str, goal: str, chat_history: List[Dict[str, Any]], retry_count: int = 0 + self, reply: str, goal: str, chat_history: List[Dict[str, Any]], chat_history_str: str, retry_count: int = 0 ) -> Tuple[bool, str, bool]: """检查回复是否合适 @@ -185,4 +182,4 @@ class ReplyGenerator: Returns: Tuple[bool, str, bool]: (是否合适, 原因, 是否需要重新规划) """ - return await self.reply_checker.check(reply, goal, chat_history, retry_count) + return await self.reply_checker.check(reply, goal, chat_history, chat_history_str, retry_count)