diff --git a/src/chat/focus_chat/heartflow_message_processor.py b/src/chat/focus_chat/heartflow_message_processor.py index 5671a6c14..a01e11e73 100644 --- a/src/chat/focus_chat/heartflow_message_processor.py +++ b/src/chat/focus_chat/heartflow_message_processor.py @@ -150,7 +150,6 @@ class HeartFCMessageReceiver: Args: message_data: 原始消息字符串 """ - message = None try: # 1. 消息解析与初始化 groupinfo = message.message_info.group_info diff --git a/src/chat/focus_chat/planners/modify_actions.py b/src/chat/focus_chat/planners/modify_actions.py index f160e6dbb..24771afce 100644 --- a/src/chat/focus_chat/planners/modify_actions.py +++ b/src/chat/focus_chat/planners/modify_actions.py @@ -131,6 +131,12 @@ class ActionModifier: f"{self.log_prefix}传统动作修改完成,当前使用动作: {list(self.action_manager.get_using_actions().keys())}" ) + # === chat_mode检查:强制移除非auto模式下的exit_focus_chat === + if global_config.chat.chat_mode != "auto": + if "exit_focus_chat" in self.action_manager.get_using_actions(): + self.action_manager.remove_action_from_using("exit_focus_chat") + logger.info(f"{self.log_prefix}移除动作: exit_focus_chat,原因: chat_mode不为auto(当前模式: {global_config.chat.chat_mode})") + # === 第二阶段:激活类型判定 === # 如果提供了聊天上下文,则进行激活类型判定 if chat_content is not None: @@ -194,8 +200,12 @@ class ActionModifier: # 恢复exit_focus_chat动作(如果之前存在) if exit_focus_action: - self.action_manager.add_action_to_using("exit_focus_chat") - logger.debug(f"{self.log_prefix}恢复exit_focus_chat动作") + # 只有在auto模式下才恢复exit_focus_chat动作 + if global_config.chat.chat_mode == "auto": + self.action_manager.add_action_to_using("exit_focus_chat") + logger.debug(f"{self.log_prefix}恢复exit_focus_chat动作") + else: + logger.debug(f"{self.log_prefix}跳过恢复exit_focus_chat动作,原因: chat_mode不为auto(当前模式: {global_config.chat.chat_mode})") logger.info(f"{self.log_prefix}激活类型判定完成,最终可用动作: {list(final_activated_actions.keys())}") diff --git a/src/chat/heart_flow/observation/chatting_observation.py b/src/chat/heart_flow/observation/chatting_observation.py index 4660038fa..213cafbc3 100644 --- a/src/chat/heart_flow/observation/chatting_observation.py +++ b/src/chat/heart_flow/observation/chatting_observation.py @@ -22,13 +22,13 @@ Prompt( """这是qq群聊的聊天记录,请总结以下聊天记录的主题: {chat_logs} 请概括这段聊天记录的主题和主要内容 -主题:简短的概括,包括时间,人物和事件,不要超过10个字 -内容:具体的信息内容,包括人物、事件和信息,不要超过100个字,不要分点。 +主题:简短的概括,包括时间,人物和事件,不要超过20个字 +内容:具体的信息内容,包括人物、事件和信息,不要超过200个字,不要分点。 请用json格式返回,格式如下: {{ - "theme": "主题", - "content": "内容" + "theme": "主题,例如 2025-06-14 10:00:00 群聊 麦麦 和 网友 讨论了 游戏 的话题", + "content": "内容,可以是对聊天记录的概括,也可以是聊天记录的详细内容" }} """, "chat_summary_group_prompt", # Template for group chat diff --git a/src/chat/normal_chat/normal_chat_action_modifier.py b/src/chat/normal_chat/normal_chat_action_modifier.py index cc57c92f6..102d63a18 100644 --- a/src/chat/normal_chat/normal_chat_action_modifier.py +++ b/src/chat/normal_chat/normal_chat_action_modifier.py @@ -184,12 +184,13 @@ class NormalChatActionModifier: activated_actions = {} # 特殊处理 change_to_focus_chat 动作 - if "change_to_focus_chat" in actions_with_info: - # 检查是否满足切换到focus模式的条件 - if await self._check_should_switch_to_focus(recent_replies): - activated_actions["change_to_focus_chat"] = actions_with_info["change_to_focus_chat"] - logger.debug(f"{self.log_prefix} 特殊激活 change_to_focus_chat 动作,原因: 满足切换到focus模式条件") - return activated_actions + if global_config.chat.chat_mode == "auto": + if "change_to_focus_chat" in actions_with_info: + # 检查是否满足切换到focus模式的条件 + if await self._check_should_switch_to_focus(recent_replies): + activated_actions["change_to_focus_chat"] = actions_with_info["change_to_focus_chat"] + logger.debug(f"{self.log_prefix} 特殊激活 change_to_focus_chat 动作,原因: 满足切换到focus模式条件") + return activated_actions # 分类处理不同激活类型的actions always_actions = {} diff --git a/src/plugins/built_in/core_actions/plugin.py b/src/plugins/built_in/core_actions/plugin.py index 5af9564d2..72a2da738 100644 --- a/src/plugins/built_in/core_actions/plugin.py +++ b/src/plugins/built_in/core_actions/plugin.py @@ -83,6 +83,9 @@ class ReplyAction(BaseAction): action_data=self.action_data, ) + # 重置NoReplyAction的连续计数器 + NoReplyAction.reset_consecutive_count() + return success, reply_text except Exception as e: @@ -142,6 +145,12 @@ class NoReplyAction(BaseAction): # 默认超时时间,将由插件在注册时设置 waiting_timeout = 1200 + + # 连续no_reply计数器 + _consecutive_count = 0 + + # 分级等待时间 + _waiting_stages = [10, 60, 600] # 第1、2、3次的等待时间 # 动作参数定义 action_parameters = {} @@ -155,17 +164,41 @@ class NoReplyAction(BaseAction): async def execute(self) -> Tuple[bool, str]: """执行不回复动作,等待新消息或超时""" try: - # 使用类属性中的超时时间 - timeout = self.waiting_timeout + # 增加连续计数 + NoReplyAction._consecutive_count += 1 + count = NoReplyAction._consecutive_count + + # 计算本次等待时间 + timeout = self._calculate_waiting_time(count) - logger.info(f"{self.log_prefix} 选择不回复,等待新消息中... (超时: {timeout}秒)") + logger.info(f"{self.log_prefix} 选择不回复(第{count}次连续),等待新消息中... (超时: {timeout}秒)") # 等待新消息或达到时间上限 - return await self.api.wait_for_new_message(timeout) + result = await self.api.wait_for_new_message(timeout) + + # 如果有新消息或者超时,都不重置计数器,因为可能还会继续no_reply + return result except Exception as e: logger.error(f"{self.log_prefix} 不回复动作执行失败: {e}") return False, f"不回复动作执行失败: {e}" + + def _calculate_waiting_time(self, consecutive_count: int) -> int: + """根据连续次数计算等待时间""" + if consecutive_count <= len(self._waiting_stages): + # 前3次使用预设时间 + stage_time = self._waiting_stages[consecutive_count - 1] + # 如果WAITING_TIME_THRESHOLD更小,则使用它 + return min(stage_time, self.waiting_timeout) + else: + # 第4次及以后使用WAITING_TIME_THRESHOLD + return self.waiting_timeout + + @classmethod + def reset_consecutive_count(cls): + """重置连续计数器""" + cls._consecutive_count = 0 + logger.debug("NoReplyAction连续计数器已重置") class EmojiAction(BaseAction): @@ -224,6 +257,9 @@ class EmojiAction(BaseAction): # 构建回复文本 reply_text = self._build_reply_text(reply_set) + # 重置NoReplyAction的连续计数器 + NoReplyAction.reset_consecutive_count() + return success, reply_text except Exception as e: @@ -273,6 +309,10 @@ class ChangeToFocusChatAction(BaseAction): async def execute(self) -> Tuple[bool, str]: """执行切换到专注聊天动作""" logger.info(f"{self.log_prefix} 决定切换到专注聊天: {self.reasoning}") + + # 重置NoReplyAction的连续计数器 + NoReplyAction.reset_consecutive_count() + # 这里只做决策标记,具体切换逻辑由上层管理器处理 return True, "决定切换到专注聊天模式" @@ -317,6 +357,9 @@ class ExitFocusChatAction(BaseAction): # 标记状态切换请求 self._mark_state_change() + # 重置NoReplyAction的连续计数器 + NoReplyAction.reset_consecutive_count() + status_message = "决定退出专注聊天模式" return True, status_message