diff --git a/src/api/config_api.py b/src/api/config_api.py index 3e3ff286c..d28b1e809 100644 --- a/src/api/config_api.py +++ b/src/api/config_api.py @@ -62,7 +62,6 @@ class APIBotConfig: # focus_chat reply_trigger_threshold: float # 回复触发阈值 default_decay_rate_per_second: float # 默认每秒衰减率 - consecutive_no_reply_threshold: int # 连续不回复阈值 # compressed compressed_length: int # 压缩长度 diff --git a/src/chat/heart_flow/interest_chatting.py b/src/chat/heart_flow/interest_chatting.py deleted file mode 100644 index 8e493179f..000000000 --- a/src/chat/heart_flow/interest_chatting.py +++ /dev/null @@ -1,199 +0,0 @@ -import asyncio -from typing import Optional, Dict -import traceback -from src.common.logger_manager import get_logger -from src.chat.message_receive.message import MessageRecv -import math - - -# 定义常量 (从 interest.py 移动过来) -MAX_INTEREST = 15.0 - -logger = get_logger("interest_chatting") - -PROBABILITY_INCREASE_RATE_PER_SECOND = 0.1 -PROBABILITY_DECREASE_RATE_PER_SECOND = 0.1 -MAX_REPLY_PROBABILITY = 1 - - -class InterestChatting: - def __init__( - self, - decay_rate=0.95, - max_interest=MAX_INTEREST, - trigger_threshold=4, - max_probability=MAX_REPLY_PROBABILITY, - ): - # 基础属性初始化 - self.interest_level: float = 0.0 - self.decay_rate_per_second: float = decay_rate - self.max_interest: float = max_interest - - self.trigger_threshold: float = trigger_threshold - self.max_reply_probability: float = max_probability - self.is_above_threshold: bool = False - - # 任务相关属性初始化 - self.update_task: Optional[asyncio.Task] = None - self._stop_event = asyncio.Event() - self._task_lock = asyncio.Lock() - self._is_running = False - - self.interest_dict: Dict[str, tuple[MessageRecv, float, bool]] = {} - self.update_interval = 1.0 - - self.above_threshold = False - self.start_hfc_probability = 0.0 - - async def initialize(self): - async with self._task_lock: - if self._is_running: - logger.debug("后台兴趣更新任务已在运行中。") - return - - # 清理已完成或已取消的任务 - if self.update_task and (self.update_task.done() or self.update_task.cancelled()): - self.update_task = None - - if not self.update_task: - self._stop_event.clear() - self._is_running = True - self.update_task = asyncio.create_task(self._run_update_loop(self.update_interval)) - logger.debug("后台兴趣更新任务已创建并启动。") - - def add_interest_dict(self, message: MessageRecv, interest_value: float, is_mentioned: bool): - """添加消息到兴趣字典 - - 参数: - message: 接收到的消息 - interest_value: 兴趣值 - is_mentioned: 是否被提及 - - 功能: - 1. 将消息添加到兴趣字典 - 2. 更新最后交互时间 - 3. 如果字典长度超过10,删除最旧的消息 - """ - # 添加新消息 - self.interest_dict[message.message_info.message_id] = (message, interest_value, is_mentioned) - - # 如果字典长度超过10,删除最旧的消息 - if len(self.interest_dict) > 10: - oldest_key = next(iter(self.interest_dict)) - self.interest_dict.pop(oldest_key) - - async def _calculate_decay(self): - """计算兴趣值的衰减 - - 参数: - current_time: 当前时间戳 - - 处理逻辑: - 1. 计算时间差 - 2. 处理各种异常情况(负值/零值) - 3. 正常计算衰减 - 4. 更新最后更新时间 - """ - - # 处理极小兴趣值情况 - if self.interest_level < 1e-9: - self.interest_level = 0.0 - return - - # 异常情况处理 - if self.decay_rate_per_second <= 0: - logger.warning(f"衰减率({self.decay_rate_per_second})无效,重置兴趣值为0") - self.interest_level = 0.0 - return - - # 正常衰减计算 - try: - decay_factor = math.pow(self.decay_rate_per_second, self.update_interval) - self.interest_level *= decay_factor - except ValueError as e: - logger.error( - f"衰减计算错误: {e} 参数: 衰减率={self.decay_rate_per_second} 时间差={self.update_interval} 当前兴趣={self.interest_level}" - ) - self.interest_level = 0.0 - - async def _update_reply_probability(self): - self.above_threshold = self.interest_level >= self.trigger_threshold - if self.above_threshold: - self.start_hfc_probability += PROBABILITY_INCREASE_RATE_PER_SECOND - else: - if self.start_hfc_probability > 0: - self.start_hfc_probability = max(0, self.start_hfc_probability - PROBABILITY_DECREASE_RATE_PER_SECOND) - - async def increase_interest(self, value: float): - self.interest_level += value - self.interest_level = min(self.interest_level, self.max_interest) - - async def decrease_interest(self, value: float): - self.interest_level -= value - self.interest_level = max(self.interest_level, 0.0) - - async def get_interest(self) -> float: - return self.interest_level - - async def get_state(self) -> dict: - interest = self.interest_level # 直接使用属性值 - return { - "interest_level": round(interest, 2), - "start_hfc_probability": round(self.start_hfc_probability, 4), - "above_threshold": self.above_threshold, - } - - # --- 新增后台更新任务相关方法 --- - async def _run_update_loop(self, update_interval: float = 1.0): - """后台循环,定期更新兴趣和回复概率。""" - try: - while not self._stop_event.is_set(): - try: - if self.interest_level != 0: - await self._calculate_decay() - - await self._update_reply_probability() - - # 等待下一个周期或停止事件 - await asyncio.wait_for(self._stop_event.wait(), timeout=update_interval) - except asyncio.TimeoutError: - # 正常超时,继续循环 - continue - except Exception as e: - logger.error(f"InterestChatting 更新循环出错: {e}") - logger.error(traceback.format_exc()) - # 防止错误导致CPU飙升,稍作等待 - await asyncio.sleep(5) - except asyncio.CancelledError: - logger.info("InterestChatting 更新循环被取消。") - finally: - self._is_running = False - logger.info("InterestChatting 更新循环已停止。") - - async def stop_updates(self): - """停止后台更新任务,使用锁确保并发安全""" - async with self._task_lock: - if not self._is_running: - logger.debug("后台兴趣更新任务未运行。") - return - - logger.info("正在停止 InterestChatting 后台更新任务...") - self._stop_event.set() - - if self.update_task and not self.update_task.done(): - try: - # 等待任务结束,设置超时 - await asyncio.wait_for(self.update_task, timeout=5.0) - logger.info("InterestChatting 后台更新任务已成功停止。") - except asyncio.TimeoutError: - logger.warning("停止 InterestChatting 后台任务超时,尝试取消...") - self.update_task.cancel() - try: - await self.update_task # 等待取消完成 - except asyncio.CancelledError: - logger.info("InterestChatting 后台更新任务已被取消。") - except Exception as e: - logger.error(f"停止 InterestChatting 后台任务时发生异常: {e}") - finally: - self.update_task = None - self._is_running = False diff --git a/src/chat/normal_chat/normal_chat_generator.py b/src/chat/normal_chat/normal_chat_generator.py index 6debc8ed6..b55d41e7c 100644 --- a/src/chat/normal_chat/normal_chat_generator.py +++ b/src/chat/normal_chat/normal_chat_generator.py @@ -38,7 +38,7 @@ class NormalChatGenerator: async def generate_response(self, message: MessageThinking, thinking_id: str) -> Optional[Union[str, List[str]]]: """根据当前模型类型选择对应的生成函数""" # 从global_config中获取模型概率值并选择模型 - if random.random() < global_config.normal_chat.reasoning_model_probability: + if random.random() < global_config.normal_chat.normal_chat_first_probability: self.current_model_type = "深深地" current_model = self.model_reasoning else: diff --git a/src/config/official_configs.py b/src/config/official_configs.py index 4814052a7..afd6676b1 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -76,7 +76,7 @@ class MessageReceiveConfig(ConfigBase): class NormalChatConfig(ConfigBase): """普通聊天配置类""" - reasoning_model_probability: float = 0.3 + normal_chat_first_probability: float = 0.3 """ 发言时选择推理模型的概率(0-1之间) 选择普通模型的概率为 1 - reasoning_normal_model_probability @@ -132,9 +132,6 @@ class FocusChatConfig(ConfigBase): observation_context_size: int = 12 """可观察到的最长上下文大小,超过这个值的上下文会被压缩""" - consecutive_no_reply_threshold: int = 3 - """连续不回复的次数阈值""" - compressed_length: int = 5 """心流上下文压缩的最短压缩长度,超过心流观察到的上下文长度,会压缩,最短压缩长度为5""" diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index 87eba0ba2..1b7a3feb5 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -63,7 +63,7 @@ ban_msgs_regex = [ [normal_chat] #普通聊天 #一般回复参数 -reasoning_model_probability = 0.3 # 麦麦回答时选择推理模型的概率(与之相对的,普通模型的概率为1 - reasoning_model_probability) +normal_chat_first_probability = 0.3 # 麦麦回答时选择首要模型的概率(与之相对的,次要模型的概率为1 - normal_chat_first_probability) max_context_size = 15 #上下文长度 emoji_chance = 0.2 # 麦麦一般回复时使用表情包的概率,设置为1让麦麦自己决定发不发 thinking_timeout = 120 # 麦麦最长思考时间,超过这个时间的思考会放弃(往往是api反应太慢) @@ -81,7 +81,6 @@ talk_frequency_down_groups = [] #降低回复频率的群号码 [focus_chat] #专注聊天 auto_focus_threshold = 1 # 自动切换到专注聊天的阈值,越低越容易进入专注聊天 exit_focus_threshold = 1 # 自动退出专注聊天的阈值,越低越容易退出专注聊天 -consecutive_no_reply_threshold = 3 # 连续不回复的阈值,越低越容易结束专注聊天 think_interval = 3 # 思考间隔 单位秒,可以有效减少消耗