From de2736fccdd7b8a72f6c4d24871077c29afcf9da Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Tue, 20 May 2025 23:34:33 +0800 Subject: [PATCH] =?UTF-8?q?better:=E5=8F=AF=E9=80=9A=E8=BF=87=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=E8=87=AA=E5=AE=9A=E4=B9=89=20?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E5=A4=84=E7=90=86=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/chat/focus_chat/heartFC_chat.py | 68 +++++++++++++++++-- .../focus_chat/heartflow_message_revceiver.py | 4 +- src/chat/heart_flow/sub_heartflow.py | 23 ++++--- src/chat/heart_flow/subheartflow_manager.py | 9 ++- src/config/config.py | 2 + src/config/official_configs.py | 5 ++ template/bot_config_template.toml | 2 +- 7 files changed, 88 insertions(+), 25 deletions(-) diff --git a/src/chat/focus_chat/heartFC_chat.py b/src/chat/focus_chat/heartFC_chat.py index 1fe7d49bf..90cdeec67 100644 --- a/src/chat/focus_chat/heartFC_chat.py +++ b/src/chat/focus_chat/heartFC_chat.py @@ -30,6 +30,16 @@ from src.config.config import global_config install(extra_lines=3) +# 定义处理器映射 +PROCESSOR_CLASSES = { + "ChattingInfoProcessor": ChattingInfoProcessor, + "MindProcessor": MindProcessor, + "ToolProcessor": ToolProcessor, + "WorkingMemoryProcessor": WorkingMemoryProcessor, + "SelfProcessor": SelfProcessor, +} + + WAITING_TIME_THRESHOLD = 300 # 等待新消息时间阈值,单位秒 EMOJI_SEND_PRO = 0.3 # 设置一个概率,比如 30% 才真的发 @@ -90,6 +100,30 @@ class HeartFChatting: observe_id=self.stream_id, working_memory=self.working_memory ) + # 根据配置文件和默认规则确定启用的处理器 + PROCESSOR_NAME_TO_CONFIG_KEY_MAP = { + "SelfProcessor": "self_identify_processor", + "ToolProcessor": "tool_use_processor", + "WorkingMemoryProcessor": "working_memory_processor", + } + self.enabled_processor_names: List[str] = [] + config_processor_settings = global_config.focus_chat_processor # 获取处理器配置,若不存在则为空字典 + + for proc_name in PROCESSOR_CLASSES.keys(): + config_key = PROCESSOR_NAME_TO_CONFIG_KEY_MAP.get(proc_name) + if config_key: + # 此处理器可通过配置控制 + # getattr(config_processor_settings, config_key, True) + # 如果config_processor_settings是字典,则用 config_processor_settings.get(config_key, True) + if getattr(config_processor_settings, config_key, True): # 默认启用,如果配置中未指定 + self.enabled_processor_names.append(proc_name) + else: + # 此处理器不在配置映射中,默认启用 + self.enabled_processor_names.append(proc_name) + + logger.info(f"{self.log_prefix} 将启用的处理器: {self.enabled_processor_names}") + + self.expressor = DefaultExpressor(chat_id=self.stream_id) self.action_manager = ActionManager() self.action_planner = ActionPlanner(log_prefix=self.log_prefix, action_manager=self.action_manager) @@ -150,13 +184,33 @@ class HeartFChatting: return True def _register_default_processors(self): - """注册默认的信息处理器""" - self.processors.append(ChattingInfoProcessor()) - self.processors.append(MindProcessor(subheartflow_id=self.stream_id)) - self.processors.append(ToolProcessor(subheartflow_id=self.stream_id)) - self.processors.append(WorkingMemoryProcessor(subheartflow_id=self.stream_id)) - self.processors.append(SelfProcessor(subheartflow_id=self.stream_id)) - logger.info(f"{self.log_prefix} 已注册默认处理器: {[p.__class__.__name__ for p in self.processors]}") + """根据 self.enabled_processor_names 注册信息处理器""" + self.processors = [] # 清空已有的 + + # self.enabled_processor_names 由 __init__ 保证是一个列表 + for name in self.enabled_processor_names: # 'name' is "ChattingInfoProcessor", etc. + processor_class = PROCESSOR_CLASSES.get(name) + if processor_class: + # 根据处理器类名判断是否需要 subheartflow_id + if name in ["MindProcessor", "ToolProcessor", "WorkingMemoryProcessor", "SelfProcessor"]: + self.processors.append(processor_class(subheartflow_id=self.stream_id)) + elif name == "ChattingInfoProcessor": + self.processors.append(processor_class()) + else: + # 对于PROCESSOR_CLASSES中定义但此处未明确处理构造的处理器 + try: + self.processors.append(processor_class()) # 尝试无参构造 + logger.debug(f"{self.log_prefix} 注册处理器 {name} (尝试无参构造).") + except TypeError: + logger.error(f"{self.log_prefix} 处理器 {name} 构造失败。它可能需要参数(如 subheartflow_id)但未在注册逻辑中明确处理。") + else: + # 这理论上不应该发生,因为 enabled_processor_names 是从 PROCESSOR_CLASSES 的键生成的 + logger.warning(f"{self.log_prefix} 在 PROCESSOR_CLASSES 中未找到名为 '{name}' 的处理器,将跳过注册。") + + if self.processors: + logger.info(f"{self.log_prefix} 已根据配置和默认规则注册处理器: {[p.__class__.__name__ for p in self.processors]}") + else: + logger.warning(f"{self.log_prefix} 没有注册任何处理器。这可能是由于配置错误或所有处理器都被禁用了。") async def start(self): """ diff --git a/src/chat/focus_chat/heartflow_message_revceiver.py b/src/chat/focus_chat/heartflow_message_revceiver.py index 9f5c78c30..0e5cc0534 100644 --- a/src/chat/focus_chat/heartflow_message_revceiver.py +++ b/src/chat/focus_chat/heartflow_message_revceiver.py @@ -111,7 +111,7 @@ def _check_ban_words(text: str, chat, userinfo) -> bool: Returns: bool: 是否包含过滤词 """ - for word in global_config.chat.ban_words: + for word in global_config.message_receive.ban_words: if word in text: chat_name = chat.group_info.group_name if chat.group_info else "私聊" logger.info(f"[{chat_name}]{userinfo.user_nickname}:{text}") @@ -131,7 +131,7 @@ def _check_ban_regex(text: str, chat, userinfo) -> bool: Returns: bool: 是否匹配过滤正则 """ - for pattern in global_config.chat.ban_msgs_regex: + for pattern in global_config.message_receive.ban_msgs_regex: if pattern.search(text): chat_name = chat.group_info.group_name if chat.group_info else "私聊" logger.info(f"[{chat_name}]{userinfo.user_nickname}:{text}") diff --git a/src/chat/heart_flow/sub_heartflow.py b/src/chat/heart_flow/sub_heartflow.py index 4019abe7d..b046744c1 100644 --- a/src/chat/heart_flow/sub_heartflow.py +++ b/src/chat/heart_flow/sub_heartflow.py @@ -13,6 +13,7 @@ from src.chat.heart_flow.mai_state_manager import MaiStateInfo from src.chat.heart_flow.chat_state_info import ChatState, ChatStateInfo from .utils_chat import get_chat_type_and_target_info from .interest_chatting import InterestChatting +from src.config.config import global_config logger = get_logger("sub_heartflow") @@ -87,13 +88,13 @@ class SubHeartflow: await self.interest_chatting.initialize() logger.debug(f"{self.log_prefix} InterestChatting 实例已初始化。") - # 创建并初始化 normal_chat_instance - chat_stream = chat_manager.get_stream(self.chat_id) - if chat_stream: - self.normal_chat_instance = NormalChat(chat_stream=chat_stream, interest_dict=self.get_interest_dict()) - await self.normal_chat_instance.initialize() - await self.normal_chat_instance.start_chat() - logger.info(f"{self.log_prefix} NormalChat 实例已创建并启动。") + # 根据配置决定初始状态 + if global_config.chat.chat_mode == "focus": + logger.info(f"{self.log_prefix} 配置为 focus 模式,将直接尝试进入 FOCUSED 状态。") + await self.change_chat_state(ChatState.FOCUSED) + else: # "auto" 或其他模式保持原有逻辑或默认为 NORMAL + logger.info(f"{self.log_prefix} 配置为 auto 或其他模式,将尝试进入 NORMAL 状态。") + await self.change_chat_state(ChatState.NORMAL) def update_last_chat_state_time(self): self.chat_state_last_time = time.time() - self.chat_state_changed_time @@ -126,10 +127,9 @@ class SubHeartflow: if not chat_stream: logger.error(f"{log_prefix} 无法获取 chat_stream,无法启动 NormalChat。") return False - if rewind: + # 在 rewind 为 True 或 NormalChat 实例尚未创建时,创建新实例 + if rewind or not self.normal_chat_instance: self.normal_chat_instance = NormalChat(chat_stream=chat_stream, interest_dict=self.get_interest_dict()) - else: - self.normal_chat_instance = NormalChat(chat_stream=chat_stream) # 进行异步初始化 await self.normal_chat_instance.initialize() @@ -185,9 +185,12 @@ class SubHeartflow: logger.info(f"{log_prefix} 麦麦准备开始专注聊天...") try: # 创建 HeartFChatting 实例,并传递 从构造函数传入的 回调函数 + + self.heart_fc_instance = HeartFChatting( chat_id=self.subheartflow_id, observations=self.observations, + ) # 初始化并启动 HeartFChatting diff --git a/src/chat/heart_flow/subheartflow_manager.py b/src/chat/heart_flow/subheartflow_manager.py index a557392d1..06b60def1 100644 --- a/src/chat/heart_flow/subheartflow_manager.py +++ b/src/chat/heart_flow/subheartflow_manager.py @@ -104,15 +104,14 @@ class SubHeartflowManager: self.mai_state_info, ) - # 异步初始化 - await new_subflow.initialize() - - # 添加聊天观察者 + # 首先创建并添加聊天观察者 observation = ChattingObservation(chat_id=subheartflow_id) await observation.initialize() - new_subflow.add_observation(observation) + # 然后再进行异步初始化,此时 SubHeartflow 内部若需启动 HeartFChatting,就能拿到 observation + await new_subflow.initialize() + # 注册子心流 self.subheartflows[subheartflow_id] = new_subflow heartflow_name = chat_manager.get_stream_name(subheartflow_id) or subheartflow_id diff --git a/src/config/config.py b/src/config/config.py index b963e61d0..b3a09850c 100644 --- a/src/config/config.py +++ b/src/config/config.py @@ -29,6 +29,7 @@ from src.config.official_configs import ( TelemetryConfig, ExperimentalConfig, ModelConfig, + FocusChatProcessorConfig, MessageReceiveConfig, ) @@ -145,6 +146,7 @@ class Config(ConfigBase): message_receive: MessageReceiveConfig normal_chat: NormalChatConfig focus_chat: FocusChatConfig + focus_chat_processor: FocusChatProcessorConfig emoji: EmojiConfig expression: ExpressionConfig memory: MemoryConfig diff --git a/src/config/official_configs.py b/src/config/official_configs.py index 82abf3ce7..f75afcf6a 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -151,6 +151,11 @@ class FocusChatConfig(ConfigBase): think_interval: int = 1 """思考间隔(秒)""" + +@dataclass +class FocusChatProcessorConfig(ConfigBase): + """专注聊天处理器配置类""" + self_identify_processor: bool = True """是否启用自我识别处理器""" diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index 60aab8d00..cb13de768 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -91,7 +91,7 @@ observation_context_size = 15 # 观察到的最长上下文大小,建议15,太 compressed_length = 5 # 不能大于chat.observation_context_size,心流上下文压缩的最短压缩长度,超过心流观察到的上下文长度,会压缩,最短压缩长度为5 compress_length_limit = 5 #最多压缩份数,超过该数值的压缩上下文会被删除 -[focus_chat.processor] # 专注聊天处理器,打开可以实现更多功能,但是会增加token消耗 +[focus_chat_processor] # 专注聊天处理器,打开可以实现更多功能,但是会增加token消耗 self_identify_processor = true # 是否启用自我识别处理器 tool_use_processor = true # 是否启用工具使用处理器 working_memory_processor = true # 是否启用工作记忆处理器