🤖 自动格式化代码 [skip ci]

This commit is contained in:
github-actions[bot]
2025-04-24 03:17:06 +00:00
parent b92e0891a1
commit 49c4d77c97
7 changed files with 238 additions and 193 deletions

View File

@@ -513,7 +513,9 @@ CONFIRM_STYLE_CONFIG = {
# 根据SIMPLE_OUTPUT选择配置 # 根据SIMPLE_OUTPUT选择配置
MAIN_STYLE_CONFIG = MAIN_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else MAIN_STYLE_CONFIG["advanced"] MAIN_STYLE_CONFIG = MAIN_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else MAIN_STYLE_CONFIG["advanced"]
EMOJI_STYLE_CONFIG = EMOJI_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else EMOJI_STYLE_CONFIG["advanced"] EMOJI_STYLE_CONFIG = EMOJI_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else EMOJI_STYLE_CONFIG["advanced"]
PFC_ACTION_PLANNER_STYLE_CONFIG = PFC_ACTION_PLANNER_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PFC_ACTION_PLANNER_STYLE_CONFIG["advanced"] PFC_ACTION_PLANNER_STYLE_CONFIG = (
PFC_ACTION_PLANNER_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PFC_ACTION_PLANNER_STYLE_CONFIG["advanced"]
)
REMOTE_STYLE_CONFIG = REMOTE_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else REMOTE_STYLE_CONFIG["advanced"] REMOTE_STYLE_CONFIG = REMOTE_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else REMOTE_STYLE_CONFIG["advanced"]
BASE_TOOL_STYLE_CONFIG = BASE_TOOL_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else BASE_TOOL_STYLE_CONFIG["advanced"] BASE_TOOL_STYLE_CONFIG = BASE_TOOL_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else BASE_TOOL_STYLE_CONFIG["advanced"]
PERSON_INFO_STYLE_CONFIG = PERSON_INFO_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PERSON_INFO_STYLE_CONFIG["advanced"] PERSON_INFO_STYLE_CONFIG = PERSON_INFO_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PERSON_INFO_STYLE_CONFIG["advanced"]

View File

@@ -16,6 +16,7 @@ pfc_action_log_config = LogConfig(
logger = get_module_logger("action_planner", config=pfc_action_log_config) logger = get_module_logger("action_planner", config=pfc_action_log_config)
# 注意:这个 ActionPlannerInfo 类似乎没有在 ActionPlanner 中使用, # 注意:这个 ActionPlannerInfo 类似乎没有在 ActionPlanner 中使用,
# 如果确实没用,可以考虑移除,但暂时保留以防万一。 # 如果确实没用,可以考虑移除,但暂时保留以防万一。
class ActionPlannerInfo: class ActionPlannerInfo:
@@ -25,9 +26,11 @@ class ActionPlannerInfo:
self.knowledge_list = [] self.knowledge_list = []
self.memory_list = [] self.memory_list = []
# ActionPlanner 类定义,顶格 # ActionPlanner 类定义,顶格
class ActionPlanner: class ActionPlanner:
"""行动规划器""" """行动规划器"""
def __init__(self, stream_id: str): def __init__(self, stream_id: str):
self.llm = LLMRequest( self.llm = LLMRequest(
model=global_config.llm_PFC_action_planner, model=global_config.llm_PFC_action_planner,
@@ -54,18 +57,20 @@ class ActionPlanner:
time_since_last_bot_message_info = "" time_since_last_bot_message_info = ""
try: try:
bot_id = str(global_config.BOT_QQ) bot_id = str(global_config.BOT_QQ)
if hasattr(observation_info, 'chat_history') and observation_info.chat_history: if hasattr(observation_info, "chat_history") and observation_info.chat_history:
for i in range(len(observation_info.chat_history) - 1, -1, -1): for i in range(len(observation_info.chat_history) - 1, -1, -1):
msg = observation_info.chat_history[i] msg = observation_info.chat_history[i]
if not isinstance(msg, dict): if not isinstance(msg, dict):
continue continue
sender_info = msg.get('user_info', {}) sender_info = msg.get("user_info", {})
sender_id = str(sender_info.get('user_id')) if isinstance(sender_info, dict) else None sender_id = str(sender_info.get("user_id")) if isinstance(sender_info, dict) else None
msg_time = msg.get('time') msg_time = msg.get("time")
if sender_id == bot_id and msg_time: if sender_id == bot_id and msg_time:
time_diff = time.time() - msg_time time_diff = time.time() - msg_time
if time_diff < 60.0: if time_diff < 60.0:
time_since_last_bot_message_info = f"提示:你上一条成功发送的消息是在 {time_diff:.1f} 秒前。\n" time_since_last_bot_message_info = (
f"提示:你上一条成功发送的消息是在 {time_diff:.1f} 秒前。\n"
)
break break
else: else:
logger.debug("Observation info chat history is empty or not available for bot time check.") logger.debug("Observation info chat history is empty or not available for bot time check.")
@@ -76,31 +81,31 @@ class ActionPlanner:
# --- 获取 Bot 上次发言时间信息结束 --- # --- 获取 Bot 上次发言时间信息结束 ---
timeout_context = "" timeout_context = ""
try: # 添加 try-except 以增加健壮性 try: # 添加 try-except 以增加健壮性
if hasattr(conversation_info, 'goal_list') and conversation_info.goal_list: if hasattr(conversation_info, "goal_list") and conversation_info.goal_list:
last_goal_tuple = conversation_info.goal_list[-1] last_goal_tuple = conversation_info.goal_list[-1]
if isinstance(last_goal_tuple, tuple) and len(last_goal_tuple) > 0: if isinstance(last_goal_tuple, tuple) and len(last_goal_tuple) > 0:
last_goal_text = last_goal_tuple[0] last_goal_text = last_goal_tuple[0]
if isinstance(last_goal_text, str) and "分钟,思考接下来要做什么" in last_goal_text: if isinstance(last_goal_text, str) and "分钟,思考接下来要做什么" in last_goal_text:
try: try:
timeout_minutes_text = last_goal_text.split('')[0].replace('你等待了','') timeout_minutes_text = last_goal_text.split("")[0].replace("你等待了", "")
timeout_context = f"重要提示:你刚刚因为对方长时间({timeout_minutes_text})没有回复而结束了等待,这可能代表在对方看来本次聊天已结束,请基于此情况规划下一步,不要重复等待前的发言。\n" timeout_context = f"重要提示:你刚刚因为对方长时间({timeout_minutes_text})没有回复而结束了等待,这可能代表在对方看来本次聊天已结束,请基于此情况规划下一步,不要重复等待前的发言。\n"
except Exception: except Exception:
timeout_context = "重要提示:你刚刚因为对方长时间没有回复而结束了等待,这可能代表在对方看来本次聊天已结束,请基于此情况规划下一步,不要重复等待前的发言。\n" timeout_context = "重要提示:你刚刚因为对方长时间没有回复而结束了等待,这可能代表在对方看来本次聊天已结束,请基于此情况规划下一步,不要重复等待前的发言。\n"
else: else:
logger.debug("Conversation info goal_list is empty or not available for timeout check.") logger.debug("Conversation info goal_list is empty or not available for timeout check.")
except AttributeError: except AttributeError:
logger.warning("ConversationInfo object might not have goal_list attribute yet for timeout check.") logger.warning("ConversationInfo object might not have goal_list attribute yet for timeout check.")
except Exception as e: except Exception as e:
logger.warning(f"检查超时目标时出错: {e}") logger.warning(f"检查超时目标时出错: {e}")
# 构建提示词 # 构建提示词
logger.debug(f"开始规划行动:当前目标: {getattr(conversation_info, 'goal_list', '不可用')}") # 使用 getattr logger.debug(f"开始规划行动:当前目标: {getattr(conversation_info, 'goal_list', '不可用')}") # 使用 getattr
# 构建对话目标 (goals_str) # 构建对话目标 (goals_str)
goals_str = "" goals_str = ""
try: # 添加 try-except try: # 添加 try-except
if hasattr(conversation_info, 'goal_list') and conversation_info.goal_list: if hasattr(conversation_info, "goal_list") and conversation_info.goal_list:
for goal_reason in conversation_info.goal_list: for goal_reason in conversation_info.goal_list:
if isinstance(goal_reason, tuple) and len(goal_reason) > 0: if isinstance(goal_reason, tuple) and len(goal_reason) > 0:
goal = goal_reason[0] goal = goal_reason[0]
@@ -114,36 +119,36 @@ class ActionPlanner:
goal = str(goal) if goal is not None else "目标内容缺失" goal = str(goal) if goal is not None else "目标内容缺失"
reasoning = str(reasoning) if reasoning is not None else "没有明确原因" reasoning = str(reasoning) if reasoning is not None else "没有明确原因"
goals_str += f"- 目标:{goal}\n 原因:{reasoning}\n" goals_str += f"- 目标:{goal}\n 原因:{reasoning}\n"
if not goals_str: # 如果循环后 goals_str 仍为空 if not goals_str: # 如果循环后 goals_str 仍为空
goals_str = "- 目前没有明确对话目标,请考虑设定一个。\n" goals_str = "- 目前没有明确对话目标,请考虑设定一个。\n"
except AttributeError: except AttributeError:
logger.warning("ConversationInfo object might not have goal_list attribute yet.") logger.warning("ConversationInfo object might not have goal_list attribute yet.")
goals_str = "- 获取对话目标时出错。\n" goals_str = "- 获取对话目标时出错。\n"
except Exception as e: except Exception as e:
logger.error(f"构建对话目标字符串时出错: {e}") logger.error(f"构建对话目标字符串时出错: {e}")
goals_str = "- 构建对话目标时出错。\n" goals_str = "- 构建对话目标时出错。\n"
# 获取聊天历史记录 (chat_history_text) # 获取聊天历史记录 (chat_history_text)
chat_history_text = "" chat_history_text = ""
try: try:
if hasattr(observation_info, 'chat_history') and observation_info.chat_history: if hasattr(observation_info, "chat_history") and observation_info.chat_history:
chat_history_list = observation_info.chat_history[-20:] chat_history_list = observation_info.chat_history[-20:]
for msg in chat_history_list: for msg in chat_history_list:
if isinstance(msg, dict) and 'detailed_plain_text' in msg: if isinstance(msg, dict) and "detailed_plain_text" in msg:
chat_history_text += f"{msg.get('detailed_plain_text', '')}\n" chat_history_text += f"{msg.get('detailed_plain_text', '')}\n"
elif isinstance(msg, str): elif isinstance(msg, str):
chat_history_text += f"{msg}\n" chat_history_text += f"{msg}\n"
if not chat_history_text: # 如果历史记录是空列表 if not chat_history_text: # 如果历史记录是空列表
chat_history_text = "还没有聊天记录。\n" chat_history_text = "还没有聊天记录。\n"
else: else:
chat_history_text = "还没有聊天记录。\n" chat_history_text = "还没有聊天记录。\n"
if hasattr(observation_info, 'new_messages_count') and observation_info.new_messages_count > 0: 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: if hasattr(observation_info, "unprocessed_messages") and observation_info.unprocessed_messages:
new_messages_list = observation_info.unprocessed_messages new_messages_list = observation_info.unprocessed_messages
chat_history_text += f"--- 以下是 {observation_info.new_messages_count} 条新消息 ---\n" chat_history_text += f"--- 以下是 {observation_info.new_messages_count} 条新消息 ---\n"
for msg in new_messages_list: for msg in new_messages_list:
if isinstance(msg, dict) and 'detailed_plain_text' in msg: if isinstance(msg, dict) and "detailed_plain_text" in msg:
chat_history_text += f"{msg.get('detailed_plain_text', '')}\n" chat_history_text += f"{msg.get('detailed_plain_text', '')}\n"
elif isinstance(msg, str): elif isinstance(msg, str):
chat_history_text += f"{msg}\n" chat_history_text += f"{msg}\n"
@@ -151,7 +156,9 @@ class ActionPlanner:
# if hasattr(observation_info, 'clear_unprocessed_messages'): # if hasattr(observation_info, 'clear_unprocessed_messages'):
# observation_info.clear_unprocessed_messages() # observation_info.clear_unprocessed_messages()
else: else:
logger.warning("ObservationInfo has new_messages_count > 0 but unprocessed_messages is empty or missing.") logger.warning(
"ObservationInfo has new_messages_count > 0 but unprocessed_messages is empty or missing."
)
except AttributeError: except AttributeError:
logger.warning("ObservationInfo object might be missing expected attributes for chat history.") logger.warning("ObservationInfo object might be missing expected attributes for chat history.")
chat_history_text = "获取聊天记录时出错。\n" chat_history_text = "获取聊天记录时出错。\n"
@@ -159,7 +166,6 @@ class ActionPlanner:
logger.error(f"处理聊天记录时发生未知错误: {e}") logger.error(f"处理聊天记录时发生未知错误: {e}")
chat_history_text = "处理聊天记录时出错。\n" chat_history_text = "处理聊天记录时出错。\n"
# 构建 Persona 文本 (persona_text) # 构建 Persona 文本 (persona_text)
identity_details_only = self.identity_detail_info identity_details_only = self.identity_detail_info
identity_addon = "" identity_addon = ""
@@ -168,11 +174,11 @@ class ActionPlanner:
# original_details = identity_details_only # original_details = identity_details_only
for p in pronouns: for p in pronouns:
if identity_details_only.startswith(p): if identity_details_only.startswith(p):
identity_details_only = identity_details_only[len(p):] identity_details_only = identity_details_only[len(p) :]
break break
if identity_details_only.endswith(""): if identity_details_only.endswith(""):
identity_details_only = identity_details_only[:-1] identity_details_only = identity_details_only[:-1]
cleaned_details = identity_details_only.strip(', ') cleaned_details = identity_details_only.strip(", ")
if cleaned_details: if cleaned_details:
identity_addon = f"并且{cleaned_details}" identity_addon = f"并且{cleaned_details}"
persona_text = f"你的名字是{self.name}{self.personality_info}{identity_addon}" persona_text = f"你的名字是{self.name}{self.personality_info}{identity_addon}"
@@ -182,15 +188,15 @@ class ActionPlanner:
last_action_context = "关于你【上一次尝试】的行动:\n" last_action_context = "关于你【上一次尝试】的行动:\n"
action_history_list = [] action_history_list = []
try: # 添加 try-except try: # 添加 try-except
if hasattr(conversation_info, 'done_action') and conversation_info.done_action: if hasattr(conversation_info, "done_action") and conversation_info.done_action:
action_history_list = conversation_info.done_action[-5:] action_history_list = conversation_info.done_action[-5:]
else: else:
logger.debug("Conversation info done_action is empty or not available.") logger.debug("Conversation info done_action is empty or not available.")
except AttributeError: except AttributeError:
logger.warning("ConversationInfo object might not have done_action attribute yet.") logger.warning("ConversationInfo object might not have done_action attribute yet.")
except Exception as e: except Exception as e:
logger.error(f"访问行动历史时出错: {e}") logger.error(f"访问行动历史时出错: {e}")
if not action_history_list: if not action_history_list:
action_history_summary += "- 还没有执行过行动。\n" action_history_summary += "- 还没有执行过行动。\n"
@@ -231,9 +237,9 @@ class ActionPlanner:
elif status == "recall": elif status == "recall":
last_action_context += "- 但该行动最终【未能执行/被取消】。\n" last_action_context += "- 但该行动最终【未能执行/被取消】。\n"
if final_reason: if final_reason:
last_action_context += f"- 【重要】失败/取消的具体原因是: “{final_reason}\n" last_action_context += f"- 【重要】失败/取消的具体原因是: “{final_reason}\n"
else: else:
last_action_context += "- 【重要】失败/取消原因未明确记录。\n" last_action_context += "- 【重要】失败/取消原因未明确记录。\n"
else: else:
last_action_context += f"- 该行动当前状态: {status}\n" last_action_context += f"- 该行动当前状态: {status}\n"
@@ -279,14 +285,15 @@ end_conversation: 决定结束对话,对方长时间没回复或者当你觉
logger.debug(f"LLM原始返回内容: {content}") logger.debug(f"LLM原始返回内容: {content}")
success, result = get_items_from_json( success, result = get_items_from_json(
content, "action", "reason", content,
default_values={"action": "wait", "reason": "LLM返回格式错误或未提供原因默认等待"} "action",
"reason",
default_values={"action": "wait", "reason": "LLM返回格式错误或未提供原因默认等待"},
) )
action = result.get("action", "wait") action = result.get("action", "wait")
reason = result.get("reason", "LLM未提供原因默认等待") reason = result.get("reason", "LLM未提供原因默认等待")
# 验证action类型 # 验证action类型
valid_actions = ["direct_reply", "fetch_knowledge", "wait", "listening", "rethink_goal", "end_conversation"] valid_actions = ["direct_reply", "fetch_knowledge", "wait", "listening", "rethink_goal", "end_conversation"]
if action not in valid_actions: if action not in valid_actions:

View File

@@ -75,13 +75,13 @@ class Conversation:
raise raise
try: try:
logger.info(f"{self.stream_id} 加载初始聊天记录...") logger.info(f"{self.stream_id} 加载初始聊天记录...")
storage = MongoDBMessageStorage() # 创建存储实例 storage = MongoDBMessageStorage() # 创建存储实例
# 获取当前时间点之前最多 N 条消息 (比如 30 条) # 获取当前时间点之前最多 N 条消息 (比如 30 条)
# get_messages_before 返回的是按时间正序排列的列表 # get_messages_before 返回的是按时间正序排列的列表
initial_messages = await storage.get_messages_before( initial_messages = await storage.get_messages_before(
chat_id=self.stream_id, chat_id=self.stream_id,
time_point=time.time(), time_point=time.time(),
limit=30 # 加载最近20条作为初始上下文可以调整 limit=30, # 加载最近20条作为初始上下文可以调整
) )
if initial_messages: if initial_messages:
# 将加载的消息填充到 ObservationInfo 的 chat_history # 将加载的消息填充到 ObservationInfo 的 chat_history
@@ -90,7 +90,7 @@ class Conversation:
# 更新 ObservationInfo 中的时间戳等信息 # 更新 ObservationInfo 中的时间戳等信息
last_msg = initial_messages[-1] last_msg = initial_messages[-1]
self.observation_info.last_message_time = last_msg.get('time') self.observation_info.last_message_time = last_msg.get("time")
last_user_info = UserInfo.from_dict(last_msg.get("user_info", {})) last_user_info = UserInfo.from_dict(last_msg.get("user_info", {}))
self.observation_info.last_message_sender = last_user_info.user_id self.observation_info.last_message_sender = last_user_info.user_id
self.observation_info.last_message_content = last_msg.get("processed_plain_text", "") self.observation_info.last_message_content = last_msg.get("processed_plain_text", "")
@@ -98,11 +98,13 @@ class Conversation:
# (可选)可以遍历 initial_messages 来设置 last_bot_speak_time 和 last_user_speak_time # (可选)可以遍历 initial_messages 来设置 last_bot_speak_time 和 last_user_speak_time
# 这里为了简化,只用了最后一条消息的时间,如果需要精确的发言者时间需要遍历 # 这里为了简化,只用了最后一条消息的时间,如果需要精确的发言者时间需要遍历
logger.info(f"成功加载 {len(initial_messages)} 条初始聊天记录。最后一条消息时间: {self.observation_info.last_message_time}") logger.info(
f"成功加载 {len(initial_messages)} 条初始聊天记录。最后一条消息时间: {self.observation_info.last_message_time}"
)
# 让 ChatObserver 从加载的最后一条消息之后开始同步 # 让 ChatObserver 从加载的最后一条消息之后开始同步
self.chat_observer.last_message_time = self.observation_info.last_message_time self.chat_observer.last_message_time = self.observation_info.last_message_time
self.chat_observer.last_message_read = last_msg # 更新 observer 的最后读取记录 self.chat_observer.last_message_read = last_msg # 更新 observer 的最后读取记录
else: else:
logger.info("没有找到初始聊天记录。") logger.info("没有找到初始聊天记录。")
@@ -128,49 +130,52 @@ class Conversation:
try: try:
# --- 在规划前记录当前新消息数量 --- # --- 在规划前记录当前新消息数量 ---
initial_new_message_count = 0 initial_new_message_count = 0
if hasattr(self.observation_info, 'new_messages_count'): if hasattr(self.observation_info, "new_messages_count"):
initial_new_message_count = self.observation_info.new_messages_count initial_new_message_count = self.observation_info.new_messages_count
else: else:
logger.warning("ObservationInfo missing 'new_messages_count' before planning.") logger.warning("ObservationInfo missing 'new_messages_count' before planning.")
# 使用决策信息来辅助行动规划 # 使用决策信息来辅助行动规划
action, reason = await self.action_planner.plan(self.observation_info, self.conversation_info) # 注意plan 函数内部现在不应再调用 clear_unprocessed_messages action, reason = await self.action_planner.plan(
self.observation_info, self.conversation_info
) # 注意plan 函数内部现在不应再调用 clear_unprocessed_messages
# --- 规划后检查是否有 *更多* 新消息到达 --- # --- 规划后检查是否有 *更多* 新消息到达 ---
current_new_message_count = 0 current_new_message_count = 0
if hasattr(self.observation_info, 'new_messages_count'): if hasattr(self.observation_info, "new_messages_count"):
current_new_message_count = self.observation_info.new_messages_count current_new_message_count = self.observation_info.new_messages_count
else: else:
logger.warning("ObservationInfo missing 'new_messages_count' after planning.") logger.warning("ObservationInfo missing 'new_messages_count' after planning.")
if current_new_message_count > initial_new_message_count: if current_new_message_count > initial_new_message_count:
# 只有当规划期间消息数量 *增加* 了,才认为需要重新规划 # 只有当规划期间消息数量 *增加* 了,才认为需要重新规划
logger.info(f"规划期间发现新增消息 ({initial_new_message_count} -> {current_new_message_count}),跳过本次行动,重新规划") logger.info(
await asyncio.sleep(0.1) # 短暂延时 f"规划期间发现新增消息 ({initial_new_message_count} -> {current_new_message_count}),跳过本次行动,重新规划"
continue # 跳过本次行动,重新规划 )
await asyncio.sleep(0.1) # 短暂延时
continue # 跳过本次行动,重新规划
# --- 如果没有在规划期间收到更多新消息,则准备执行行动 --- # --- 如果没有在规划期间收到更多新消息,则准备执行行动 ---
# --- 清理未处理消息:移到这里,在执行动作前 --- # --- 清理未处理消息:移到这里,在执行动作前 ---
# 只有当确实有新消息被 planner 看到,并且 action 是要处理它们的时候才清理 # 只有当确实有新消息被 planner 看到,并且 action 是要处理它们的时候才清理
if initial_new_message_count > 0 and action == "direct_reply": if initial_new_message_count > 0 and action == "direct_reply":
if hasattr(self.observation_info, 'clear_unprocessed_messages'): if hasattr(self.observation_info, "clear_unprocessed_messages"):
# 确保 clear_unprocessed_messages 方法存在 # 确保 clear_unprocessed_messages 方法存在
logger.debug(f"准备执行 direct_reply清理 {initial_new_message_count} 条规划时已知的新消息。") logger.debug(f"准备执行 direct_reply清理 {initial_new_message_count} 条规划时已知的新消息。")
self.observation_info.clear_unprocessed_messages() self.observation_info.clear_unprocessed_messages()
# 手动重置计数器,确保状态一致性(理想情况下 clear 方法会做这个) # 手动重置计数器,确保状态一致性(理想情况下 clear 方法会做这个)
if hasattr(self.observation_info, 'new_messages_count'): if hasattr(self.observation_info, "new_messages_count"):
self.observation_info.new_messages_count = 0 self.observation_info.new_messages_count = 0
else: else:
logger.error("无法清理未处理消息: ObservationInfo 缺少 clear_unprocessed_messages 方法!") logger.error("无法清理未处理消息: ObservationInfo 缺少 clear_unprocessed_messages 方法!")
# 这里可能需要考虑是否继续执行 action或者抛出错误 # 这里可能需要考虑是否继续执行 action或者抛出错误
# --- 执行行动 --- # --- 执行行动 ---
await self._handle_action(action, reason, self.observation_info, self.conversation_info) await self._handle_action(action, reason, self.observation_info, self.conversation_info)
goal_ended = False goal_ended = False
if hasattr(self.conversation_info, 'goal_list') and self.conversation_info.goal_list: if hasattr(self.conversation_info, "goal_list") and self.conversation_info.goal_list:
for goal in self.conversation_info.goal_list: for goal in self.conversation_info.goal_list:
if isinstance(goal, tuple) and len(goal) > 0 and goal[0] == "结束对话": if isinstance(goal, tuple) and len(goal) > 0 and goal[0] == "结束对话":
goal_ended = True goal_ended = True
@@ -185,15 +190,15 @@ class Conversation:
# break # 可以选择在这里直接跳出循环 # break # 可以选择在这里直接跳出循环
except Exception as loop_err: except Exception as loop_err:
logger.error(f"PFC主循环出错: {loop_err}") logger.error(f"PFC主循环出错: {loop_err}")
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
# 发生严重错误时可以考虑停止,或者至少等待一下再继续 # 发生严重错误时可以考虑停止,或者至少等待一下再继续
await asyncio.sleep(1) # 发生错误时等待1秒 await asyncio.sleep(1) # 发生错误时等待1秒
#添加短暂的异步睡眠 # 添加短暂的异步睡眠
if self.should_continue: # 只有在还需要继续循环时才 sleep if self.should_continue: # 只有在还需要继续循环时才 sleep
await asyncio.sleep(0.1) # 等待 0.1 秒,给其他任务执行时间 await asyncio.sleep(0.1) # 等待 0.1 秒,给其他任务执行时间
logger.info(f"PFC 循环结束 for stream_id: {self.stream_id}") # 添加日志表明循环正常结束 logger.info(f"PFC 循环结束 for stream_id: {self.stream_id}") # 添加日志表明循环正常结束
def _check_new_messages_after_planning(self): def _check_new_messages_after_planning(self):
"""检查在规划后是否有新消息""" """检查在规划后是否有新消息"""
@@ -232,10 +237,10 @@ class Conversation:
# 记录action历史先设置为start完成后再设置为done (这个 update 移到后面执行成功后再做) # 记录action历史先设置为start完成后再设置为done (这个 update 移到后面执行成功后再做)
current_action_record = { current_action_record = {
"action": action, "action": action,
"plan_reason": reason, #使用 plan_reason 存储规划原因 "plan_reason": reason, # 使用 plan_reason 存储规划原因
"status": "start", # 初始状态为 start "status": "start", # 初始状态为 start
"time": datetime.datetime.now().strftime("%H:%M:%S"), "time": datetime.datetime.now().strftime("%H:%M:%S"),
"final_reason": None "final_reason": None,
} }
conversation_info.done_action.append(current_action_record) conversation_info.done_action.append(current_action_record)
# 获取刚刚添加记录的索引,方便后面更新状态 # 获取刚刚添加记录的索引,方便后面更新状态
@@ -244,16 +249,16 @@ class Conversation:
# --- 根据不同的 action 执行 --- # --- 根据不同的 action 执行 ---
if action == "direct_reply": if action == "direct_reply":
# --- 这个 if 块内部的所有代码都需要正确缩进 --- # --- 这个 if 块内部的所有代码都需要正确缩进 ---
self.waiter.wait_accumulated_time = 0 # 重置等待时间 self.waiter.wait_accumulated_time = 0 # 重置等待时间
self.state = ConversationState.GENERATING self.state = ConversationState.GENERATING
# 生成回复 # 生成回复
self.generated_reply = await self.reply_generator.generate(observation_info, conversation_info) self.generated_reply = await self.reply_generator.generate(observation_info, conversation_info)
logger.info(f"生成回复: {self.generated_reply}") # 使用 logger logger.info(f"生成回复: {self.generated_reply}") # 使用 logger
# --- 调用 ReplyChecker 检查回复 --- # --- 调用 ReplyChecker 检查回复 ---
is_suitable = False # 先假定不合适,检查通过再改为 True is_suitable = False # 先假定不合适,检查通过再改为 True
check_reason = "检查未执行" # 用不同的变量名存储检查原因 check_reason = "检查未执行" # 用不同的变量名存储检查原因
need_replan = False need_replan = False
try: try:
# 尝试获取当前主要目标 # 尝试获取当前主要目标
@@ -263,14 +268,14 @@ class Conversation:
is_suitable, check_reason, need_replan = await self.reply_generator.check_reply( is_suitable, check_reason, need_replan = await self.reply_generator.check_reply(
reply=self.generated_reply, reply=self.generated_reply,
goal=current_goal_str, goal=current_goal_str,
chat_history=observation_info.chat_history, # 传入最新的历史记录! chat_history=observation_info.chat_history, # 传入最新的历史记录!
retry_count=0 retry_count=0,
) )
logger.info(f"回复检查结果: 合适={is_suitable}, 原因='{check_reason}', 需重新规划={need_replan}") logger.info(f"回复检查结果: 合适={is_suitable}, 原因='{check_reason}', 需重新规划={need_replan}")
except Exception as check_err: except Exception as check_err:
logger.error(f"调用 ReplyChecker 时出错: {check_err}") logger.error(f"调用 ReplyChecker 时出错: {check_err}")
check_reason = f"检查过程出错: {check_err}" # 记录错误原因 check_reason = f"检查过程出错: {check_err}" # 记录错误原因
# is_suitable 保持 False # is_suitable 保持 False
# --- 处理检查结果 --- # --- 处理检查结果 ---
@@ -280,31 +285,37 @@ class Conversation:
if self._check_new_messages_after_planning(): if self._check_new_messages_after_planning():
logger.info("检查到新消息,取消发送已生成的回复,重新规划行动") logger.info("检查到新消息,取消发送已生成的回复,重新规划行动")
# 更新 action 状态为 recall # 更新 action 状态为 recall
conversation_info.done_action[action_index].update({ conversation_info.done_action[action_index].update(
"status": "recall", {
"reason": f"有新消息,取消发送: {self.generated_reply}", # 更新原因 "status": "recall",
"time": datetime.datetime.now().strftime("%H:%M:%S"), "reason": f"有新消息,取消发送: {self.generated_reply}", # 更新原因
}) "time": datetime.datetime.now().strftime("%H:%M:%S"),
return None # 退出 _handle_action }
)
return None # 退出 _handle_action
# 发送回复 # 发送回复
await self._send_reply() # 这个函数内部会处理自己的错误 await self._send_reply() # 这个函数内部会处理自己的错误
# 更新 action 历史状态为 done # 更新 action 历史状态为 done
conversation_info.done_action[action_index].update({ conversation_info.done_action[action_index].update(
"status": "done", {
"time": datetime.datetime.now().strftime("%H:%M:%S"), "status": "done",
}) "time": datetime.datetime.now().strftime("%H:%M:%S"),
}
)
else: else:
# 回复不合适 # 回复不合适
logger.warning(f"生成的回复被 ReplyChecker 拒绝: '{self.generated_reply}'. 原因: {check_reason}") logger.warning(f"生成的回复被 ReplyChecker 拒绝: '{self.generated_reply}'. 原因: {check_reason}")
# 更新 action 状态为 recall (因为没执行发送) # 更新 action 状态为 recall (因为没执行发送)
conversation_info.done_action[action_index].update({ conversation_info.done_action[action_index].update(
"status": "recall", {
"final_reason": check_reason, "status": "recall",
"time": datetime.datetime.now().strftime("%H:%M:%S"), "final_reason": check_reason,
}) "time": datetime.datetime.now().strftime("%H:%M:%S"),
}
)
# 如果检查器建议重新规划 # 如果检查器建议重新规划
if need_replan: if need_replan:
@@ -323,22 +334,26 @@ class Conversation:
topic = "TODO:关键词" topic = "TODO:关键词"
logger.info(f"假装获取到知识{knowledge},关键词是: {topic}") logger.info(f"假装获取到知识{knowledge},关键词是: {topic}")
if knowledge: if knowledge:
pass # 简单处理 pass # 简单处理
# 标记 action 为 done # 标记 action 为 done
conversation_info.done_action[action_index].update({ conversation_info.done_action[action_index].update(
"status": "done", {
"time": datetime.datetime.now().strftime("%H:%M:%S"), "status": "done",
}) "time": datetime.datetime.now().strftime("%H:%M:%S"),
}
)
elif action == "rethink_goal": elif action == "rethink_goal":
self.waiter.wait_accumulated_time = 0 self.waiter.wait_accumulated_time = 0
self.state = ConversationState.RETHINKING self.state = ConversationState.RETHINKING
await self.goal_analyzer.analyze_goal(conversation_info, observation_info) await self.goal_analyzer.analyze_goal(conversation_info, observation_info)
# 标记 action 为 done # 标记 action 为 done
conversation_info.done_action[action_index].update({ conversation_info.done_action[action_index].update(
"status": "done", {
"time": datetime.datetime.now().strftime("%H:%M:%S"), "status": "done",
}) "time": datetime.datetime.now().strftime("%H:%M:%S"),
}
)
elif action == "listening": elif action == "listening":
self.state = ConversationState.LISTENING self.state = ConversationState.LISTENING
@@ -347,31 +362,36 @@ class Conversation:
# listening 和 wait 通常在完成后不需要标记为 done因为它们是持续状态 # listening 和 wait 通常在完成后不需要标记为 done因为它们是持续状态
# 但如果需要记录,可以在 waiter 返回后标记。目前逻辑是 waiter 返回后主循环继续。 # 但如果需要记录,可以在 waiter 返回后标记。目前逻辑是 waiter 返回后主循环继续。
# 为了统一,可以暂时在这里也标记一下(或者都不标记) # 为了统一,可以暂时在这里也标记一下(或者都不标记)
conversation_info.done_action[action_index].update({ conversation_info.done_action[action_index].update(
"status": "done", # 或 "completed" {
"time": datetime.datetime.now().strftime("%H:%M:%S"), "status": "done", # 或 "completed"
}) "time": datetime.datetime.now().strftime("%H:%M:%S"),
}
)
elif action == "end_conversation": elif action == "end_conversation":
self.should_continue = False # 设置循环停止标志 self.should_continue = False # 设置循环停止标志
logger.info("决定结束对话...") logger.info("决定结束对话...")
# 标记 action 为 done # 标记 action 为 done
conversation_info.done_action[action_index].update({ conversation_info.done_action[action_index].update(
"status": "done", {
"time": datetime.datetime.now().strftime("%H:%M:%S"), "status": "done",
}) "time": datetime.datetime.now().strftime("%H:%M:%S"),
}
)
# 这里不需要 return主循环会在下一轮检查 should_continue # 这里不需要 return主循环会在下一轮检查 should_continue
else: # 对应 'wait' 动作 else: # 对应 'wait' 动作
self.state = ConversationState.WAITING self.state = ConversationState.WAITING
logger.info("等待更多信息...") logger.info("等待更多信息...")
await self.waiter.wait(self.conversation_info) await self.waiter.wait(self.conversation_info)
# 同 listening可以考虑是否标记状态 # 同 listening可以考虑是否标记状态
conversation_info.done_action[action_index].update({ conversation_info.done_action[action_index].update(
"status": "done", # 或 "completed" {
"time": datetime.datetime.now().strftime("%H:%M:%S"), "status": "done", # 或 "completed"
}) "time": datetime.datetime.now().strftime("%H:%M:%S"),
}
)
async def _send_timeout_message(self): async def _send_timeout_message(self):
"""发送超时结束消息""" """发送超时结束消息"""
@@ -395,35 +415,35 @@ class Conversation:
try: try:
# 外层 try: 捕获发送消息和后续处理中的主要错误 # 外层 try: 捕获发送消息和后续处理中的主要错误
current_time = time.time() # 获取当前时间戳 current_time = time.time() # 获取当前时间戳
reply_content = self.generated_reply # 获取要发送的内容 reply_content = self.generated_reply # 获取要发送的内容
# 发送消息 # 发送消息
await self.direct_sender.send_message(chat_stream=self.chat_stream, content=reply_content) await self.direct_sender.send_message(chat_stream=self.chat_stream, content=reply_content)
logger.info(f"消息已发送: {reply_content}") # 可以在发送后加个日志确认 logger.info(f"消息已发送: {reply_content}") # 可以在发送后加个日志确认
# --- 添加的立即更新状态逻辑开始 --- # --- 添加的立即更新状态逻辑开始 ---
try: try:
# 内层 try: 专门捕获手动更新状态时可能出现的错误 # 内层 try: 专门捕获手动更新状态时可能出现的错误
# 创建一个代表刚刚发送的消息的字典 # 创建一个代表刚刚发送的消息的字典
bot_message_info = { bot_message_info = {
"message_id": f"bot_sent_{current_time}", # 创建一个简单的唯一ID "message_id": f"bot_sent_{current_time}", # 创建一个简单的唯一ID
"time": current_time, "time": current_time,
"user_info": UserInfo( # 使用 UserInfo 类构建用户信息 "user_info": UserInfo( # 使用 UserInfo 类构建用户信息
user_id=str(global_config.BOT_QQ), user_id=str(global_config.BOT_QQ),
user_nickname=global_config.BOT_NICKNAME, user_nickname=global_config.BOT_NICKNAME,
platform=self.chat_stream.platform # 从 chat_stream 获取平台信息 platform=self.chat_stream.platform, # 从 chat_stream 获取平台信息
).to_dict(), # 转换为字典格式存储 ).to_dict(), # 转换为字典格式存储
"processed_plain_text": reply_content, # 使用发送的内容 "processed_plain_text": reply_content, # 使用发送的内容
"detailed_plain_text": f"{int(current_time)},{global_config.BOT_NICKNAME}:{reply_content}", # 构造一个简单的详细文本, 时间戳取整 "detailed_plain_text": f"{int(current_time)},{global_config.BOT_NICKNAME}:{reply_content}", # 构造一个简单的详细文本, 时间戳取整
# 可以根据需要添加其他字段,保持与 observation_info.chat_history 中其他消息结构一致 # 可以根据需要添加其他字段,保持与 observation_info.chat_history 中其他消息结构一致
} }
# 直接更新 ObservationInfo 实例 # 直接更新 ObservationInfo 实例
if self.observation_info: if self.observation_info:
self.observation_info.chat_history.append(bot_message_info) # 将消息添加到历史记录末尾 self.observation_info.chat_history.append(bot_message_info) # 将消息添加到历史记录末尾
self.observation_info.last_bot_speak_time = current_time # 更新 Bot 最后发言时间 self.observation_info.last_bot_speak_time = current_time # 更新 Bot 最后发言时间
self.observation_info.last_message_time = current_time # 更新最后消息时间 self.observation_info.last_message_time = current_time # 更新最后消息时间
logger.debug("已手动将Bot发送的消息添加到 ObservationInfo") logger.debug("已手动将Bot发送的消息添加到 ObservationInfo")
else: else:
logger.warning("无法手动更新 ObservationInfo实例不存在") logger.warning("无法手动更新 ObservationInfo实例不存在")
@@ -432,15 +452,14 @@ class Conversation:
logger.error(f"手动更新 ObservationInfo 时出错: {update_err}") logger.error(f"手动更新 ObservationInfo 时出错: {update_err}")
# --- 添加的立即更新状态逻辑结束 --- # --- 添加的立即更新状态逻辑结束 ---
# 原有的触发更新和等待代码 # 原有的触发更新和等待代码
self.chat_observer.trigger_update() self.chat_observer.trigger_update()
if not await self.chat_observer.wait_for_update(): if not await self.chat_observer.wait_for_update():
logger.warning("等待 ChatObserver 更新完成超时") logger.warning("等待 ChatObserver 更新完成超时")
self.state = ConversationState.ANALYZING # 更新对话状态 self.state = ConversationState.ANALYZING # 更新对话状态
except Exception as e: except Exception as e:
# 这是外层 try 对应的 except # 这是外层 try 对应的 except
logger.error(f"发送消息或更新状态时失败: {str(e)}") logger.error(f"发送消息或更新状态时失败: {str(e)}")
self.state = ConversationState.ANALYZING # 出错也要尝试恢复状态 self.state = ConversationState.ANALYZING # 出错也要尝试恢复状态

View File

@@ -100,11 +100,11 @@ class GoalAnalyzer:
pronouns = ["", "", ""] pronouns = ["", "", ""]
for p in pronouns: for p in pronouns:
if identity_details_only.startswith(p): if identity_details_only.startswith(p):
identity_details_only = identity_details_only[len(p):] identity_details_only = identity_details_only[len(p) :]
break break
if identity_details_only.endswith(""): if identity_details_only.endswith(""):
identity_details_only = identity_details_only[:-1] identity_details_only = identity_details_only[:-1]
cleaned_details = identity_details_only.strip(', ') cleaned_details = identity_details_only.strip(", ")
if cleaned_details: if cleaned_details:
identity_addon = f"并且{cleaned_details}" identity_addon = f"并且{cleaned_details}"
@@ -263,18 +263,18 @@ class GoalAnalyzer:
pronouns = ["", "", ""] pronouns = ["", "", ""]
for p in pronouns: for p in pronouns:
if identity_details_only.startswith(p): if identity_details_only.startswith(p):
identity_details_only = identity_details_only[len(p):] identity_details_only = identity_details_only[len(p) :]
break break
if identity_details_only.endswith(""): if identity_details_only.endswith(""):
identity_details_only = identity_details_only[:-1] identity_details_only = identity_details_only[:-1]
cleaned_details = identity_details_only.strip(', ') cleaned_details = identity_details_only.strip(", ")
if cleaned_details: if cleaned_details:
identity_addon = f"并且{cleaned_details}" identity_addon = f"并且{cleaned_details}"
persona_text = f"你的名字是{self.name}{self.personality_info}{identity_addon}" persona_text = f"你的名字是{self.name}{self.personality_info}{identity_addon}"
# ===> Persona 文本构建结束 <=== # ===> Persona 文本构建结束 <===
# --- 修改 Prompt 字符串,使用 persona_text --- # --- 修改 Prompt 字符串,使用 persona_text ---
prompt = f"""{persona_text}。现在你在参与一场QQ聊天 prompt = f"""{persona_text}。现在你在参与一场QQ聊天
当前对话目标:{goal} 当前对话目标:{goal}
产生该对话目标的原因:{reasoning} 产生该对话目标的原因:{reasoning}

View File

@@ -21,7 +21,9 @@ class ReplyChecker:
self.chat_observer = ChatObserver.get_instance(stream_id) self.chat_observer = ChatObserver.get_instance(stream_id)
self.max_retries = 2 # 最大重试次数 self.max_retries = 2 # 最大重试次数
async def check(self, reply: str, goal: str, chat_history: List[Dict[str, Any]], retry_count: int = 0) -> Tuple[bool, str, bool]: async def check(
self, reply: str, goal: str, chat_history: List[Dict[str, Any]], retry_count: int = 0
) -> Tuple[bool, str, bool]:
"""检查生成的回复是否合适 """检查生成的回复是否合适
Args: Args:
@@ -40,19 +42,24 @@ class ReplyChecker:
bot_messages = [] bot_messages = []
for msg in reversed(chat_history): for msg in reversed(chat_history):
user_info = UserInfo.from_dict(msg.get("user_info", {})) user_info = UserInfo.from_dict(msg.get("user_info", {}))
if str(user_info.user_id) == str(global_config.BOT_QQ): # 确保比较的是字符串 if str(user_info.user_id) == str(global_config.BOT_QQ): # 确保比较的是字符串
bot_messages.append(msg.get('processed_plain_text', '')) bot_messages.append(msg.get("processed_plain_text", ""))
if len(bot_messages) >= 2: # 只和最近的两条比较 if len(bot_messages) >= 2: # 只和最近的两条比较
break break
# 进行比较 # 进行比较
if bot_messages: if bot_messages:
# 可以用简单比较,或者更复杂的相似度库 (如 difflib) # 可以用简单比较,或者更复杂的相似度库 (如 difflib)
# 简单比较:是否完全相同 # 简单比较:是否完全相同
if reply == bot_messages[0]: # 和最近一条完全一样 if reply == bot_messages[0]: # 和最近一条完全一样
logger.warning(f"ReplyChecker 检测到回复与上一条 Bot 消息完全相同: '{reply}'") logger.warning(f"ReplyChecker 检测到回复与上一条 Bot 消息完全相同: '{reply}'")
return False, "回复内容与你上一条发言完全相同,请修改,可以选择深入话题或寻找其它话题或等待", False # 不合适,无需重新规划 return (
False,
"回复内容与你上一条发言完全相同,请修改,可以选择深入话题或寻找其它话题或等待",
False,
) # 不合适,无需重新规划
# 2. 相似度检查 (如果精确匹配未通过) # 2. 相似度检查 (如果精确匹配未通过)
import difflib # 导入 difflib 库 import difflib # 导入 difflib 库
# 计算编辑距离相似度ratio() 返回 0 到 1 之间的浮点数 # 计算编辑距离相似度ratio() 返回 0 到 1 之间的浮点数
similarity_ratio = difflib.SequenceMatcher(None, reply, bot_messages[0]).ratio() similarity_ratio = difflib.SequenceMatcher(None, reply, bot_messages[0]).ratio()
logger.debug(f"ReplyChecker - 相似度: {similarity_ratio:.2f}") logger.debug(f"ReplyChecker - 相似度: {similarity_ratio:.2f}")
@@ -60,11 +67,17 @@ class ReplyChecker:
# 设置一个相似度阈值 # 设置一个相似度阈值
similarity_threshold = 0.9 similarity_threshold = 0.9
if similarity_ratio > similarity_threshold: if similarity_ratio > similarity_threshold:
logger.warning(f"ReplyChecker 检测到回复与上一条 Bot 消息高度相似 (相似度 {similarity_ratio:.2f}): '{reply}'") logger.warning(
return False, f"拒绝发送:回复内容与你上一条发言高度相似 (相似度 {similarity_ratio:.2f}),请修改,可以选择深入话题或寻找其它话题或等待。", False f"ReplyChecker 检测到回复与上一条 Bot 消息高度相似 (相似度 {similarity_ratio:.2f}): '{reply}'"
)
return (
False,
f"拒绝发送:回复内容与你上一条发言高度相似 (相似度 {similarity_ratio:.2f}),请修改,可以选择深入话题或寻找其它话题或等待。",
False,
)
except Exception as self_check_err: except Exception as self_check_err:
logger.error(f"检查自身重复发言时出错: {self_check_err}") logger.error(f"检查自身重复发言时出错: {self_check_err}")
for msg in chat_history[-20:]: for msg in chat_history[-20:]:
time_str = datetime.datetime.fromtimestamp(msg["time"]).strftime("%H:%M:%S") time_str = datetime.datetime.fromtimestamp(msg["time"]).strftime("%H:%M:%S")

View File

@@ -92,13 +92,13 @@ class ReplyGenerator:
pronouns = ["", "", ""] pronouns = ["", "", ""]
for p in pronouns: for p in pronouns:
if identity_details_only.startswith(p): if identity_details_only.startswith(p):
identity_details_only = identity_details_only[len(p):] identity_details_only = identity_details_only[len(p) :]
break break
if identity_details_only.endswith(""): if identity_details_only.endswith(""):
identity_details_only = identity_details_only[:-1] identity_details_only = identity_details_only[:-1]
cleaned_details = identity_details_only.strip(', ') cleaned_details = identity_details_only.strip(", ")
if cleaned_details: if cleaned_details:
identity_addon = f"并且{cleaned_details}" identity_addon = f"并且{cleaned_details}"
persona_text = f"你的名字是{self.name}{self.personality_info}{identity_addon}" persona_text = f"你的名字是{self.name}{self.personality_info}{identity_addon}"
# 构建action历史文本 # 构建action历史文本
action_history_list = ( action_history_list = (
@@ -172,7 +172,9 @@ class ReplyGenerator:
logger.error(f"生成回复时出错: {e}") logger.error(f"生成回复时出错: {e}")
return "抱歉,我现在有点混乱,让我重新思考一下..." return "抱歉,我现在有点混乱,让我重新思考一下..."
async def check_reply(self, reply: str, goal: str, chat_history: List[Dict[str, Any]], retry_count: int = 0) -> Tuple[bool, str, bool]: async def check_reply(
self, reply: str, goal: str, chat_history: List[Dict[str, Any]], retry_count: int = 0
) -> Tuple[bool, str, bool]:
"""检查回复是否合适 """检查回复是否合适
Args: Args:

View File

@@ -1,6 +1,7 @@
from src.common.logger import get_module_logger from src.common.logger import get_module_logger
from .chat_observer import ChatObserver from .chat_observer import ChatObserver
from .conversation_info import ConversationInfo from .conversation_info import ConversationInfo
# from src.individuality.individuality import Individuality # 不再需要 # from src.individuality.individuality import Individuality # 不再需要
from ...config.config import global_config from ...config.config import global_config
import time import time
@@ -12,6 +13,7 @@ logger = get_module_logger("waiter")
# 例如: 120 秒 = 2 分钟 # 例如: 120 秒 = 2 分钟
DESIRED_TIMEOUT_SECONDS = 300 DESIRED_TIMEOUT_SECONDS = 300
class Waiter: class Waiter:
"""等待处理类""" """等待处理类"""
@@ -29,7 +31,7 @@ class Waiter:
# 检查是否有新消息 # 检查是否有新消息
if self.chat_observer.new_message_after(wait_start_time): if self.chat_observer.new_message_after(wait_start_time):
logger.info("等待结束,收到新消息") logger.info("等待结束,收到新消息")
return False # 返回 False 表示不是超时 return False # 返回 False 表示不是超时
# 检查是否超时 # 检查是否超时
elapsed_time = time.time() - wait_start_time elapsed_time = time.time() - wait_start_time
@@ -41,10 +43,10 @@ class Waiter:
} }
conversation_info.goal_list.append(wait_goal) conversation_info.goal_list.append(wait_goal)
logger.info(f"添加目标: {wait_goal}") logger.info(f"添加目标: {wait_goal}")
return True # 返回 True 表示超时 return True # 返回 True 表示超时
await asyncio.sleep(5) # 每 5 秒检查一次 await asyncio.sleep(5) # 每 5 秒检查一次
logger.info("等待中...") # 可以考虑把这个频繁日志注释掉,只在超时或收到消息时输出 logger.info("等待中...") # 可以考虑把这个频繁日志注释掉,只在超时或收到消息时输出
async def wait_listening(self, conversation_info: ConversationInfo) -> bool: async def wait_listening(self, conversation_info: ConversationInfo) -> bool:
"""倾听用户发言或超时""" """倾听用户发言或超时"""
@@ -55,7 +57,7 @@ class Waiter:
# 检查是否有新消息 # 检查是否有新消息
if self.chat_observer.new_message_after(wait_start_time): if self.chat_observer.new_message_after(wait_start_time):
logger.info("倾听等待结束,收到新消息") logger.info("倾听等待结束,收到新消息")
return False # 返回 False 表示不是超时 return False # 返回 False 表示不是超时
# 检查是否超时 # 检查是否超时
elapsed_time = time.time() - wait_start_time elapsed_time = time.time() - wait_start_time
@@ -68,7 +70,7 @@ class Waiter:
} }
conversation_info.goal_list.append(wait_goal) conversation_info.goal_list.append(wait_goal)
logger.info(f"添加目标: {wait_goal}") logger.info(f"添加目标: {wait_goal}")
return True # 返回 True 表示超时 return True # 返回 True 表示超时
await asyncio.sleep(5) # 每 5 秒检查一次 await asyncio.sleep(5) # 每 5 秒检查一次
logger.info("倾听等待中...") # 同上,可以考虑注释掉 logger.info("倾听等待中...") # 同上,可以考虑注释掉