diff --git a/src/heart_flow/README.md b/src/heart_flow/README.md index cf1cd5ac0..ca6603e30 100644 --- a/src/heart_flow/README.md +++ b/src/heart_flow/README.md @@ -1,12 +1,71 @@ # 心流系统 (Heart Flow System) -## 通俗易懂的工作流程介绍 +## 一条消息是怎么到最终回复的?简明易懂的介绍 -心流系统就像一个智能聊天管家,它的工作方式可以这样理解: +1 接受消息,由HeartHC_processor处理消息,存储消息 -心流系统由主控中心(Heartflow)作为大脑协调全局,它通过场景管家(SubHeartflowManager)管理各个聊天场景的"小管家"(SubHeartflow)。当收到消息时,系统会先进行过滤和基础分析(如屏蔽词检查和兴趣度计算),然后将处理好的消息分发给对应场景的小管家。每个小管家会根据当前状态决定回复方式:不参与(ABSENT)时完全不看不回,普通模式(CHAT)进行简单回复,专注模式(FOCUSED)则深入交流。系统会根据聊天活跃度和兴趣度自动调整各场景的参与程度,同时主控中心也能手动调整整体参与度(如在离线、轻度参与和专注聊天之间切换)。整个系统就像一个拥有多个聊天助手的智能管家,能够智能地动态调整参与聊天的深度和范围。 + 1.1 process_message()函数,接受消息 -## 1. 系统架构 (System Architecture) + 1.2 创建消息对应的聊天流(chat_stream)和子心流(sub_heartflow) + + 1.3 进行常规消息处理 + + 1.4 存储消息 store_message() + + 1.5 计算兴趣度Interest + + 1.6 将消息连同兴趣度,存储到内存中的interest_dict(SubHeartflow的属性) + +2 根据 sub_heartflow 的聊天状态,决定后续处理流程 + + 2a ABSENT状态:不做任何处理 + + 2b CHAT状态:送入NormalChat 实例 + + 2c FOCUS状态:送入HeartFChatting 实例 + +b NormalChat工作方式 + + b.1 启动后台任务 _reply_interested_message,持续运行。 + b.2 该任务轮询 InterestChatting 提供的 interest_dict + b.3 对每条消息,结合兴趣度、是否被提及(@)、意愿管理器(WillingManager)计算回复概率。(这部分要改,目前还是用willing计算的,之后要和Interest合并) + b.4 若概率通过: + b.4.1 创建"思考中"消息 (MessageThinking)。 + b.4.2 调用 NormalChatGenerator 生成文本回复。 + b.4.3 通过 message_manager 发送回复 (MessageSending)。 + b.4.4 可能根据配置和文本内容,额外发送一个匹配的表情包。 + b.4.5 更新关系值和全局情绪。 + b.5 处理完成后,从 interest_dict 中移除该消息。 + +c HeartFChatting工作方式 + + c.1 启动主循环 _hfc_loop + c.2 每个循环称为一个周期 (Cycle),执行 think_plan_execute 流程。 + c.3 Think (思考) 阶段: + c.3.1 观察 (Observe): 通过 ChattingObservation,使用 observe() 获取最新的聊天消息。 + c.3.2 思考 (Think): 调用 SubMind 的 do_thinking_before_reply 方法。 + c.3.2.1 SubMind 结合观察到的内容、个性、情绪、上周期动作等信息,生成当前的内心想法 (current_mind)。 + c.3.2.2 在此过程中 SubMind 的LLM可能请求调用工具 (ToolUser) 来获取额外信息或执行操作,结果存储在 structured_info 中。 + c.4 Plan (规划/决策) 阶段: + c.4.1 结合观察到的消息文本、`SubMind` 生成的 `current_mind` 和 `structured_info`、以及 `ActionManager` 提供的可用动作,决定本次周期的行动 (`text_reply`/`emoji_reply`/`no_reply`) 和理由。 + c.4.2 重新规划检查 (Re-plan Check): 如果在 c.3.1 到 c.4.1 期间检测到新消息,可能(有概率)触发重新执行 c.4.1 决策步骤。 + c.5 Execute (执行/回复) 阶段: + c.5.1 如果决策是 text_reply: + c.5.1.1 获取锚点消息。 + c.5.1.2 通过 HeartFCSender 注册"思考中"状态。 + c.5.1.3 调用 HeartFCGenerator (gpt_instance) 生成回复文本。 + c.5.1.4 通过 HeartFCSender 发送回复 + c.5.1.5 如果规划时指定了表情查询 (emoji_query),随后发送表情。 + c.5.2 如果决策是 emoji_reply: + c.5.2.1 获取锚点消息。 + c.5.2.2 通过 HeartFCSender 直接发送匹配查询 (emoji_query) 的表情。 + c.5.3 如果决策是 no_reply: + c.5.3.1 进入等待状态,直到检测到新消息或超时。 + c.6 循环结束后,记录周期信息 (CycleInfo),并根据情况进行短暂休眠,防止CPU空转。 + + + +## 1. 一条消息是怎么到最终回复的?复杂细致的介绍 ### 1.1. 主心流 (Heartflow) - **文件**: `heartflow.py` @@ -24,7 +83,7 @@ - 维护特定场景下的思维状态和聊天流状态 (`ChatState`)。 - 通过关联的 `Observation` 实例接收和处理信息。 - 拥有独立的思考 (`SubMind`) 和回复判断能力。 -- **观察者**: 每个子心流可以拥有一个或多个 `Observation` 实例(目前每个子心流仅使用一个 `ChattingObservation`)。 +- **观察者**: 每个子心流可以拥有一个或多个 `Observation` 实例(目前每个子心流仅使用一个 `ChattingObservation`)。 - **内部结构**: - **聊天流状态 (`ChatState`)**: 标记当前子心流的参与模式 (`ABSENT`, `CHAT`, `FOCUSED`),决定是否观察、回复以及使用何种回复模式。 - **聊天实例 (`NormalChatInstance` / `HeartFlowChatInstance`)**: 根据 `ChatState` 激活对应的实例来处理聊天逻辑。同一时间只有一个实例处于活动状态。 @@ -84,21 +143,25 @@ - **状态及含义**: - `ChatState.ABSENT` (不参与/没在看): 初始或停用状态。子心流不观察新信息,不进行思考,也不回复。 - `ChatState.CHAT` (随便看看/水群): 普通聊天模式。激活 `NormalChatInstance`。 - * `ChatState.FOCUSED` (专注/激情水群): 专注聊天模式。激活 `HeartFlowChatInstance`。 + * `ChatState.FOCUSED` (专注/认真水群): 专注聊天模式。激活 `HeartFlowChatInstance`。 - **选择**: 子心流可以根据外部指令(来自 `SubHeartflowManager`)或内部逻辑(未来的扩展)选择进入 `ABSENT` 状态(不回复不观察),或进入 `CHAT` / `FOCUSED` 中的一种回复模式。 - **状态转换机制** (由 `SubHeartflowManager` 驱动): - - **激活 `CHAT`**: 当 `Heartflow` 状态从 `OFFLINE` 变为允许聊天的状态时,`SubHeartflowManager` 会根据限制,选择部分 `ABSENT` 状态的子心流,调用其 `set_chat_state` 方法将其转换为 `CHAT`。 - - **激活 `FOCUSED`**: `SubHeartflowManager` 会定期评估处于 `CHAT` 状态的子心流的兴趣度 (`InterestChatting.start_hfc_probability`),若满足条件且未达上限,则调用 `set_chat_state` 将其提升为 `FOCUSED`。 + - **激活 `CHAT`**: 当 `Heartflow` 状态从 `OFFLINE` 变为允许聊天的状态时,`SubHeartflowManager` 会根据限制,选择部分 `ABSENT` 状态的子心流,**检查当前 CHAT 状态数量是否达到上限**,如果未达上限,则调用其 `set_chat_state` 方法将其转换为 `CHAT`。 + - **激活 `FOCUSED`**: `SubHeartflowManager` 会定期评估处于 `CHAT` 状态的子心流的兴趣度 (`InterestChatting.start_hfc_probability`),若满足条件且**检查当前 FOCUSED 状态数量未达上限**,则调用 `set_chat_state` 将其提升为 `FOCUSED`。 - **停用/回退**: `SubHeartflowManager` 可能因 `Heartflow` 状态变化、达到数量限制、长时间不活跃或随机概率等原因,调用 `set_chat_state` 将子心流状态设置为 `ABSENT` 或从 `FOCUSED` 回退到 `CHAT`。 + - **注意**: `set_chat_state` 方法本身只负责执行状态转换和管理内部聊天实例(`NormalChatInstance`/`HeartFlowChatInstance`),不再进行限额检查。限额检查的责任完全由调用方(即 `SubHeartflowManager` 中的相关方法)承担。 ## 3. 聊天实例详解 (Chat Instances Explained) ### 3.1. NormalChatInstance - **激活条件**: 对应 `SubHeartflow` 的 `ChatState` 为 `CHAT`。 - **工作流程**: - - 按照系统设定的普通聊天规则处理群消息。 - - 定期检查新消息。 - - 对简单询问、闲聊等进行及时回复。 + - 当 `SubHeartflow` 进入 `CHAT` 状态时,`NormalChatInstance` 会被激活。 + - 实例启动后,会创建一个后台任务 (`_reply_interested_message`)。 + - 该任务持续监控由 `InterestChatting` 传入的、具有一定兴趣度的消息列表 (`interest_dict`)。 + - 对列表中的每条消息,结合是否被提及 (`@`)、消息本身的兴趣度以及当前的回复意愿 (`WillingManager`),计算出一个回复概率。 + - 根据计算出的概率随机决定是否对该消息进行回复。 + - 如果决定回复,则调用 `NormalChatGenerator` 生成回复内容,并可能附带表情包。 - **行为特点**: - 回复相对常规、简单。 - 不投入过多计算资源。 @@ -153,19 +216,4 @@ - `sub_heart_flow_stop_time`: 子心流停止(标记为可清理)的不活跃时间阈值 (似乎由 `SubHeartflowManager.cleanup_inactive_subheartflows` 的参数 `inactive_threshold_seconds` 控制)。 - `sub_heart_flow_freeze_time`: 子心流冻结时间 (当前文档未明确体现,可能需要审阅代码确认)。 - `heart_flow_update_interval`: 主心流更新其状态或执行管理操作的频率 (需要审阅 `Heartflow` 代码确认)。 -- `MaiStateInfo` 内的限制: 定义了不同主状态下 `CHAT` 和 `FOCUSED` 子心流的数量上限。 - -## 6. 注意事项 (Important Notes) - -1. **自动清理**: `SubHeartflowManager` 会定期检查并清理长时间不活跃的子心流。 -2. **性能平衡**: 主心流执行管理操作的频率(如检查状态、清理、评估兴趣)需要合理配置,以平衡系统性能和响应速度。 -3. **信息过载**: 单个 `ChattingObservation` 会限制一次性从数据库拉取的消息数量 (`max_now_obs_len`)。 - -## 7. 待办与未来方向 (TODOs and Future Directions) - -* **更新 "与其他模块的交互" 部分**: 详细说明 `SubHeartflowManager`, `SubHeartflow`, `NormalChatInstance`, `HeartFlowChatInstance` 之间以及与 `MessageManager`, `ResponseGenerator`, `InterestManager` 等外部模块的具体交互。 -* **明确 `sub_heart_flow_freeze_time`**: 确认该配置项的实际作用和实现位置。 -* **明确 `heart_flow_update_interval`**: 确认主心流管理循环的实际间隔。 -* **扩展观察类型**: 实现更多 `Observation` 类型(如私聊、系统事件等)。 -* **子心流内部状态转换**: 探索允许子心流根据自身思考结果主动请求状态转换的可能性。 -* **资源管理**: 优化子心流的资源占用和清理策略。 +- ` \ No newline at end of file diff --git a/src/heart_flow/chat_state_info.py b/src/heart_flow/chat_state_info.py index 14fd33403..619f372fc 100644 --- a/src/heart_flow/chat_state_info.py +++ b/src/heart_flow/chat_state_info.py @@ -5,7 +5,7 @@ import enum class ChatState(enum.Enum): ABSENT = "没在看群" CHAT = "随便水群" - FOCUSED = "激情水群" + FOCUSED = "认真水群" class ChatStateInfo: diff --git a/src/heart_flow/heartFC_chatting_logic.md b/src/heart_flow/heartFC_chatting_logic.md index 67a13cc66..1e178a6ff 100644 --- a/src/heart_flow/heartFC_chatting_logic.md +++ b/src/heart_flow/heartFC_chatting_logic.md @@ -118,7 +118,3 @@ - 是否发生了重新规划 (`replanned`) - 详细的响应信息 (`response_info`),包括生成的文本、表情查询、锚点消息 ID、实际发送的消息 ID 列表以及 `SubMind` 的思考内容。 - `HeartFChatting` 维护一个 `_cycle_history` 队列来保存最近的循环记录,方便调试和分析。 - -## 8. 总结 - -`HeartFChatting` 通过精密的循环控制、阶段分离(思考、规划、执行)、与 `SubMind` 和 `Observation` 的紧密协作,以及对 `HeartFCSender` 和 `HeartFCGenerator` 等专用组件的依赖,实现了在 FOCUSED 状态下的主动、深入且有状态的对话逻辑。它能够根据上下文和内部思考动态调整回复策略,并通过 `ActionManager` 灵活控制可执行的动作范围。 \ No newline at end of file diff --git a/src/heart_flow/sub_heartflow.py b/src/heart_flow/sub_heartflow.py index fb1a81c3b..cbdcd2748 100644 --- a/src/heart_flow/sub_heartflow.py +++ b/src/heart_flow/sub_heartflow.py @@ -232,54 +232,68 @@ class SubHeartflow: subheartflow_id: 子心流唯一标识符 parent_heartflow: 父级心流实例 """ - # 基础属性 + # 基础属性,两个值是一样的 self.subheartflow_id = subheartflow_id self.chat_id = subheartflow_id + # 麦麦的状态 self.mai_states = mai_states - # 聊天状态管理 - self.chat_state: ChatStateInfo = ChatStateInfo() # 该sub_heartflow的聊天状态信息 - self.interest_chatting = None # 将在 initialize 中创建 + # 这个聊天流的状态 + self.chat_state: ChatStateInfo = ChatStateInfo() + + # 兴趣检测器 + self.interest_chatting = None # 活动状态管理 self.last_active_time = time.time() # 最后活跃时间 self.should_stop = False # 停止标志 self.task: Optional[asyncio.Task] = None # 后台任务 + + # 随便水群 normal_chat 和 认真水群 heartFC_chat 实例 + # CHAT模式激活 随便水群 FOCUS模式激活 认真水群 self.heart_fc_instance: Optional[HeartFChatting] = None # 该sub_heartflow的HeartFChatting实例 self.normal_chat_instance: Optional[NormalChat] = None # 该sub_heartflow的NormalChat实例 - # 观察和知识系统 + # 观察,目前只有聊天观察,可以载入多个 + # 负责对处理过的消息进行观察 self.observations: List[ChattingObservation] = [] # 观察列表 - self.running_knowledges = [] # 运行中的知识 + # self.running_knowledges = [] # 运行中的知识,待完善 - # LLM模型配置 + # LLM模型配置,负责进行思考 self.sub_mind = SubMind( subheartflow_id=self.subheartflow_id, chat_state=self.chat_state, observations=self.observations ) + # 日志前缀 self.log_prefix = chat_manager.get_stream_name(self.subheartflow_id) or self.subheartflow_id async def initialize(self): - """异步初始化方法""" + """异步初始化方法,创建兴趣检测器""" self.interest_chatting = await InterestChatting.create(state_change_callback=self.set_chat_state) logger.debug(f"{self.log_prefix} InterestChatting 实例已创建并初始化。") async def add_time_current_state(self, add_time: float): + """增加当前状态的时间""" self.current_state_time += add_time async def change_to_state_chat(self): + """改变到随便水群状态""" self.current_state_time = 120 self._start_normal_chat() async def change_to_state_focused(self): + """改变到认真水群状态""" self.current_state_time = 60 self._start_heart_fc_chat() async def _stop_normal_chat(self): - """停止 NormalChat 的兴趣监控""" + """ + 停止 NormalChat 实例 + 切出 CHAT 状态时使用 + """ if self.normal_chat_instance: - logger.info(f"{self.log_prefix} 停止 NormalChat 兴趣监控...") + logger.info(f"{self.log_prefix} 离开CHAT模式,结束 随便水群") try: await self.normal_chat_instance.stop_chat() # 调用 stop_chat except Exception as e: @@ -287,23 +301,21 @@ class SubHeartflow: logger.error(traceback.format_exc()) async def _start_normal_chat(self) -> bool: - """启动 NormalChat 实例及其兴趣监控,确保 HeartFChatting 已停止""" - await self._stop_heart_fc_chat() # 确保专注聊天已停止 + """ + 启动 NormalChat 实例, + 进入 CHAT 状态时使用 + + 确保 HeartFChatting 已停止 + """ + await self._stop_heart_fc_chat() # 确保 专注聊天已停止 log_prefix = self.log_prefix try: - # 总是尝试创建或获取最新的 stream 和 interest_dict + # 获取聊天流并创建 NormalChat 实例 chat_stream = chat_manager.get_stream(self.chat_id) - if not chat_stream: - logger.error(f"{log_prefix} 无法获取 chat_stream,无法启动 NormalChat。") - return False - - # 如果实例不存在或需要更新,则创建新实例 - # if not self.normal_chat_instance: # 或者总是重新创建以获取最新的 interest_dict? self.normal_chat_instance = NormalChat(chat_stream=chat_stream, interest_dict=self.get_interest_dict()) - logger.info(f"{log_prefix} 创建或更新 NormalChat 实例。") - logger.info(f"{log_prefix} 启动 NormalChat 兴趣监控...") + logger.info(f"{log_prefix} 启动 NormalChat 随便水群...") await self.normal_chat_instance.start_chat() # <--- 修正:调用 start_chat return True except Exception as e: @@ -369,7 +381,7 @@ class SubHeartflow: self.heart_fc_instance = None # 创建或初始化异常,清理实例 return False - async def set_chat_state(self, new_state: "ChatState", current_states_num: tuple = ()): + async def set_chat_state(self, new_state: "ChatState"): """更新sub_heartflow的聊天状态,并管理 HeartFChatting 和 NormalChat 实例及任务""" current_state = self.chat_state.chat_status if current_state == new_state: @@ -377,47 +389,30 @@ class SubHeartflow: return log_prefix = self.log_prefix - current_mai_state = self.mai_states.get_current_state() state_changed = False # 标记状态是否实际发生改变 # --- 状态转换逻辑 --- if new_state == ChatState.CHAT: - normal_limit = current_mai_state.get_normal_chat_max_num() - current_chat_count = current_states_num[1] if len(current_states_num) > 1 else 0 - - if current_chat_count >= normal_limit and current_state != ChatState.CHAT: - logger.debug( - f"{log_prefix} 无法从 {current_state.value} 转到 聊天。原因:聊不过来了 ({current_chat_count}/{normal_limit})" - ) - return # 阻止状态转换 + # 移除限额检查逻辑 + logger.debug(f"{log_prefix} 准备进入或保持 聊天 状态") + if await self._start_normal_chat(): + logger.info(f"{log_prefix} 成功进入或保持 NormalChat 状态。") + state_changed = True else: - logger.debug(f"{log_prefix} 准备进入或保持 聊天 状态 ({current_chat_count}/{normal_limit})") - if await self._start_normal_chat(): - logger.info(f"{log_prefix} 成功进入或保持 NormalChat 状态。") - state_changed = True - else: - logger.error(f"{log_prefix} 启动 NormalChat 失败,无法进入 CHAT 状态。") - # 考虑是否需要回滚状态或采取其他措施 - return # 启动失败,不改变状态 + logger.error(f"{log_prefix} 启动 NormalChat 失败,无法进入 CHAT 状态。") + # 考虑是否需要回滚状态或采取其他措施 + return # 启动失败,不改变状态 elif new_state == ChatState.FOCUSED: - focused_limit = current_mai_state.get_focused_chat_max_num() - current_focused_count = current_states_num[2] if len(current_states_num) > 2 else 0 - - if current_focused_count >= focused_limit and current_state != ChatState.FOCUSED: - logger.debug( - f"{log_prefix} 无法从 {current_state.value} 转到 专注。原因:聊不过来了 ({current_focused_count}/{focused_limit})" - ) - return # 阻止状态转换 + # 移除限额检查逻辑 + logger.debug(f"{log_prefix} 准备进入或保持 专注聊天 状态") + if await self._start_heart_fc_chat(): + logger.info(f"{log_prefix} 成功进入或保持 HeartFChatting 状态。") + state_changed = True else: - logger.debug(f"{log_prefix} 准备进入或保持 专注聊天 状态 ({current_focused_count}/{focused_limit})") - if await self._start_heart_fc_chat(): - logger.info(f"{log_prefix} 成功进入或保持 HeartFChatting 状态。") - state_changed = True - else: - logger.error(f"{log_prefix} 启动 HeartFChatting 失败,无法进入 FOCUSED 状态。") - # 启动失败,状态回滚到之前的状态或ABSENT?这里保持不改变 - return # 启动失败,不改变状态 + logger.error(f"{log_prefix} 启动 HeartFChatting 失败,无法进入 FOCUSED 状态。") + # 启动失败,状态回滚到之前的状态或ABSENT?这里保持不改变 + return # 启动失败,不改变状态 elif new_state == ChatState.ABSENT: logger.info(f"{log_prefix} 进入 ABSENT 状态,停止所有聊天活动...") diff --git a/src/heart_flow/subheartflow_manager.py b/src/heart_flow/subheartflow_manager.py index 79f2a0ecf..0bfa40cc7 100644 --- a/src/heart_flow/subheartflow_manager.py +++ b/src/heart_flow/subheartflow_manager.py @@ -74,8 +74,6 @@ class SubHeartflowManager: # logger.debug(f"获取到已存在的子心流: {subheartflow_id}") return subflow - # 创建新的子心流实例 - # logger.info(f"子心流 {subheartflow_id} 不存在,正在创建...") try: # 初始化子心流 new_subflow = SubHeartflow(subheartflow_id, mai_states) @@ -118,7 +116,7 @@ class SubHeartflowManager: self.count_subflows_by_state(ChatState.CHAT), self.count_subflows_by_state(ChatState.FOCUSED), ) - await subheartflow.set_chat_state(ChatState.ABSENT, states_num) + await subheartflow.set_chat_state(ChatState.ABSENT) else: logger.debug(f"[子心流管理] {stream_name} 已是ABSENT状态") except Exception as e: @@ -235,13 +233,15 @@ class SubHeartflowManager: logger.debug(f"[激活] 正在激活子心流{stream_name}") - states_num = ( - self.count_subflows_by_state(ChatState.ABSENT), - self.count_subflows_by_state(ChatState.CHAT), - self.count_subflows_by_state(ChatState.FOCUSED), - ) + # --- 限额检查 --- # + current_chat_count = self.count_subflows_by_state(ChatState.CHAT) + if current_chat_count >= limit: + logger.warning(f"[激活] 跳过{stream_name}, 普通聊天已达上限 ({current_chat_count}/{limit})") + continue # 跳过此子心流,继续尝试激活下一个 + # --- 结束限额检查 --- # - await flow.set_chat_state(ChatState.CHAT, states_num) + # 移除 states_num 参数 + await flow.set_chat_state(ChatState.CHAT) if flow.chat_state.chat_status == ChatState.CHAT: activated_count += 1 @@ -319,11 +319,11 @@ class SubHeartflowManager: continue logger.info( - f"{log_prefix} [{stream_name}] 触发 激情水群 (概率={current_subflow.interest_chatting.start_hfc_probability:.2f})" + f"{log_prefix} [{stream_name}] 触发 认真水群 (概率={current_subflow.interest_chatting.start_hfc_probability:.2f})" ) # 执行状态提升 - await current_subflow.set_chat_state(ChatState.FOCUSED, states_num) + await current_subflow.set_chat_state(ChatState.FOCUSED) # 验证提升结果 if ( @@ -372,7 +372,7 @@ class SubHeartflowManager: # --- 状态设置 --- # # 注意:这里传递的状态数量是 *停用前* 的状态数量 - await current_subflow.set_chat_state(ChatState.ABSENT, states_num_before) + await current_subflow.set_chat_state(ChatState.ABSENT) # --- 状态验证 (可选) --- final_subflow = self.subheartflows.get(flow_id) @@ -383,7 +383,6 @@ class SubHeartflowManager: f"{log_prefix_manager} {log_prefix_flow} 成功从 {current_state.value} 停用到 ABSENT 状态" ) deactivated_count += 1 - # 注意:停用后不需要更新 states_num_before,因为它只用于 set_chat_state 的限制检查 else: logger.warning( f"{log_prefix_manager} {log_prefix_flow} 尝试停用到 ABSENT 后状态仍为 {final_state.value}" diff --git a/src/plugins/heartFC_chat/heartFC_chat.py b/src/plugins/heartFC_chat/heartFC_chat.py index bd4da95a7..e9577e411 100644 --- a/src/plugins/heartFC_chat/heartFC_chat.py +++ b/src/plugins/heartFC_chat/heartFC_chat.py @@ -216,7 +216,7 @@ class HeartFChatting: self.log_prefix = f"[{chat_manager.get_stream_name(self.stream_id) or self.stream_id}]" self._initialized = True - logger.info(f"麦麦感觉到了,可以开始激情水群{self.log_prefix} ") + logger.info(f"麦麦感觉到了,可以开始认真水群{self.log_prefix} ") return True async def start(self): @@ -224,7 +224,7 @@ class HeartFChatting: 启动 HeartFChatting 的主循环。 注意:调用此方法前必须确保已经成功初始化。 """ - logger.info(f"{self.log_prefix} 开始激情水群(HFC)...") + logger.info(f"{self.log_prefix} 开始认真水群(HFC)...") await self._start_loop_if_needed() async def _start_loop_if_needed(self): @@ -247,7 +247,7 @@ class HeartFChatting: pass # 忽略取消或超时错误 self._loop_task = None # 清理旧任务引用 - logger.info(f"{self.log_prefix} 启动激情水群(HFC)主循环...") + logger.info(f"{self.log_prefix} 启动认真水群(HFC)主循环...") # 创建新的循环任务 self._loop_task = asyncio.create_task(self._hfc_loop()) # 添加完成回调 @@ -320,7 +320,7 @@ class HeartFChatting: ) except asyncio.CancelledError: - logger.info(f"{self.log_prefix} HeartFChatting: 麦麦的激情水群(HFC)被取消了") + logger.info(f"{self.log_prefix} HeartFChatting: 麦麦的认真水群(HFC)被取消了") except Exception as e: logger.error(f"{self.log_prefix} HeartFChatting: 意外错误: {e}") logger.error(traceback.format_exc()) diff --git a/src/plugins/heartFC_chat/normal_chat.py b/src/plugins/heartFC_chat/normal_chat.py index 76cba5979..6687421e5 100644 --- a/src/plugins/heartFC_chat/normal_chat.py +++ b/src/plugins/heartFC_chat/normal_chat.py @@ -164,14 +164,13 @@ class NormalChat: ) self.mood_manager.update_mood_from_emotion(emotion, global_config.mood_intensity_factor) - async def _find_interested_message(self) -> None: + async def _reply_interested_message(self) -> None: """ 后台任务方法,轮询当前实例关联chat的兴趣消息 通常由start_monitoring_interest()启动 """ while True: - await asyncio.sleep(1) # 每秒检查一次 - + await asyncio.sleep(0.5) # 每秒检查一次 # 检查任务是否已被取消 if self._chat_task is None or self._chat_task.cancelled(): logger.info(f"[{self.stream_name}] 兴趣监控任务被取消或置空,退出") @@ -353,36 +352,27 @@ class NormalChat: async def start_chat(self): """为此 NormalChat 实例关联的 ChatStream 启动聊天任务(如果尚未运行)。""" if self._chat_task is None or self._chat_task.done(): - logger.info(f"[{self.stream_name}] 启动聊天任务...") - task = asyncio.create_task(self._find_interested_message()) + task = asyncio.create_task(self._reply_interested_message()) task.add_done_callback(lambda t: self._handle_task_completion(t)) # 回调现在是实例方法 self._chat_task = task - # 改为实例方法, 移除 stream_id 参数 def _handle_task_completion(self, task: asyncio.Task): - """兴趣监控任务完成时的回调函数。""" - # 检查完成的任务是否是当前实例的任务 + """任务完成回调处理""" if task is not self._chat_task: - logger.warning(f"[{self.stream_name}] 收到一个未知或过时任务的完成回调。") + logger.warning(f"[{self.stream_name}] 收到未知任务回调") return - try: - # 检查任务是否因异常而结束 - exception = task.exception() - if exception: - logger.error(f"[{self.stream_name}] 兴趣监控任务因异常结束: {exception}") - logger.error(traceback.format_exc()) # 记录完整的 traceback - # else: # 减少日志 - # logger.info(f"[{self.stream_name}] 兴趣监控任务正常结束。") + if exc := task.exception(): + logger.error(f"[{self.stream_name}] 任务异常: {exc}") + logger.error(traceback.format_exc()) except asyncio.CancelledError: - logger.info(f"[{self.stream_name}] 兴趣监控任务被取消。") + logger.info(f"[{self.stream_name}] 任务已取消") except Exception as e: - logger.error(f"[{self.stream_name}] 处理任务完成回调时出错: {e}") + logger.error(f"[{self.stream_name}] 回调处理错误: {e}") finally: - # 标记任务已完成/移除 - if self._chat_task is task: # 再次确认是当前任务 + if self._chat_task is task: self._chat_task = None - logger.debug(f"[{self.stream_name}] 聊天任务已被标记为完成/移除。") + logger.debug(f"[{self.stream_name}] 任务清理完成") # 改为实例方法, 移除 stream_id 参数 async def stop_chat(self): diff --git a/src/plugins/utils/chat_message_builder.py b/src/plugins/utils/chat_message_builder.py index 5d9494488..f510365fa 100644 --- a/src/plugins/utils/chat_message_builder.py +++ b/src/plugins/utils/chat_message_builder.py @@ -311,7 +311,7 @@ async def build_readable_messages( ) readable_read_mark = translate_timestamp_to_human_readable(read_mark, mode=timestamp_mode) - read_mark_line = f"\n--- 以上消息已读 (标记时间: {readable_read_mark}) ---\n--- 以下新消息未读---\n" + read_mark_line = f"\n--- 以上消息是你已经思考过的内容已读 (标记时间: {readable_read_mark}) ---\n--- 请关注以下未读的新消息---\n" # 组合结果,确保空部分不引入多余的标记或换行 if formatted_before and formatted_after: diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index a85d9f17a..afb65e89c 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -252,7 +252,7 @@ provider = "SILICONFLOW" pri_in = 0 pri_out = 0 -[model.llm_sub_heartflow] #子心流:激情水群时,生成麦麦的内心想法 +[model.llm_sub_heartflow] #子心流:认真水群时,生成麦麦的内心想法 name = "Qwen/Qwen2.5-72B-Instruct" provider = "SILICONFLOW" pri_in = 4.13 @@ -260,7 +260,7 @@ pri_out = 4.13 temp = 0.7 #模型的温度,新V3建议0.1-0.3 -[model.llm_plan] #决策模型:激情水群时,负责决定麦麦该做什么 +[model.llm_plan] #决策模型:认真水群时,负责决定麦麦该做什么 name = "Qwen/Qwen2.5-32B-Instruct" provider = "SILICONFLOW" pri_in = 1.26