From bc489861d30703fc4062494ef327226c57452485 Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Wed, 28 May 2025 20:41:46 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat=EF=BC=9A=E4=B8=BAnormal=5Fchat?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=E9=80=89=E9=A1=B9=EF=BC=8C=E6=9C=89=E6=95=88?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=9B=9E=E5=A4=8D=E9=A2=91=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelogs/changelog.md | 9 +- .../focus_chat/heartflow_message_processor.py | 18 ++- src/chat/heart_flow/background_tasks.py | 74 +--------- src/chat/heart_flow/heartflow.py | 8 +- src/chat/heart_flow/mai_state_manager.py | 135 ------------------ src/chat/heart_flow/sub_heartflow.py | 9 +- src/chat/heart_flow/subheartflow_manager.py | 5 +- src/chat/normal_chat/normal_chat.py | 66 +++++---- src/chat/normal_chat/normal_chat_utils.py | 33 +++++ src/common/logger.py | 4 +- src/config/official_configs.py | 5 +- template/bot_config_template.toml | 56 ++++---- 12 files changed, 138 insertions(+), 284 deletions(-) delete mode 100644 src/chat/heart_flow/mai_state_manager.py create mode 100644 src/chat/normal_chat/normal_chat_utils.py diff --git a/changelogs/changelog.md b/changelogs/changelog.md index 55d87d401..c4dc8b3bc 100644 --- a/changelogs/changelog.md +++ b/changelogs/changelog.md @@ -8,8 +8,8 @@ - 重构表情包模块 - 移除日程系统 -**重构专注聊天(HFC)** -- 模块化HFC,可以自定义不同的部件 +**重构专注聊天(HFC - focus_chat)** +- 模块化设计,可以自定义不同的部件 - 观察器(获取信息) - 信息处理器(处理信息) - 重构:聊天思考(子心流)处理器 @@ -31,6 +31,10 @@ - 在专注模式下,麦麦可以决定自行发送语音消息(需要搭配tts适配器) - 优化reply,减少复读 +**优化普通聊天(normal_chat)** +- 增加了talk_frequency参数来有效控制回复频率 +- 优化了进入和离开normal_chat的方式 + **新增表达方式学习** - 在专注模式下,麦麦可以有独特的表达方式 - 自主学习群聊中的表达方式,更贴近群友 @@ -50,6 +54,7 @@ **人格** - 简化了人格身份的配置 +- 优化了在focus模式下人格的表现和稳定性 **数据库重构** - 移除了默认使用MongoDB,采用轻量sqlite diff --git a/src/chat/focus_chat/heartflow_message_processor.py b/src/chat/focus_chat/heartflow_message_processor.py index c1efeb522..18349d7ab 100644 --- a/src/chat/focus_chat/heartflow_message_processor.py +++ b/src/chat/focus_chat/heartflow_message_processor.py @@ -8,6 +8,7 @@ from ..utils.utils import is_mentioned_bot_in_message from src.chat.heart_flow.heartflow import heartflow from src.common.logger_manager import get_logger from ..message_receive.chat_stream import chat_manager +import math # from ..message_receive.message_buffer import message_buffer from ..utils.timer_calculator import Timer @@ -69,6 +70,15 @@ async def _calculate_interest(message: MessageRecv) -> Tuple[float, bool]: message.processed_plain_text, fast_retrieval=True, ) + text_len = len(message.processed_plain_text) + # 根据文本长度调整兴趣度,长度越大兴趣度越高,但增长率递减,最低0.01,最高0.05 + # 采用对数函数实现递减增长 + + base_interest = 0.01 + (0.05 - 0.01) * (math.log10(text_len + 1) / math.log10(1000 + 1)) + base_interest = min(max(base_interest, 0.01), 0.05) + + interested_rate += base_interest + logger.trace(f"记忆激活率: {interested_rate:.2f}") if is_mentioned: @@ -205,17 +215,15 @@ class HeartFCMessageReceiver: # 6. 兴趣度计算与更新 interested_rate, is_mentioned = await _calculate_interest(message) - # await subheartflow.interest_chatting.increase_interest(value=interested_rate) - subheartflow.add_interest_message(message, interested_rate, is_mentioned) + subheartflow.add_message_to_normal_chat_cache(message, interested_rate, is_mentioned) # 7. 日志记录 mes_name = chat.group_info.group_name if chat.group_info else "私聊" - current_time = time.strftime("%H:%M:%S", time.localtime(message.message_info.time)) + # current_time = time.strftime("%H:%M:%S", time.localtime(message.message_info.time)) logger.info( - f"[{current_time}][{mes_name}]" + f"[{mes_name}]" f"{userinfo.user_nickname}:" f"{message.processed_plain_text}" - f"[激活: {interested_rate:.1f}]" ) # 8. 关系处理 diff --git a/src/chat/heart_flow/background_tasks.py b/src/chat/heart_flow/background_tasks.py index 9479804ea..db2604567 100644 --- a/src/chat/heart_flow/background_tasks.py +++ b/src/chat/heart_flow/background_tasks.py @@ -2,25 +2,18 @@ import asyncio import traceback from typing import Optional, Coroutine, Callable, Any, List from src.common.logger_manager import get_logger -from src.chat.heart_flow.mai_state_manager import MaiStateManager, MaiStateInfo from src.chat.heart_flow.subheartflow_manager import SubHeartflowManager from src.config.config import global_config logger = get_logger("background_tasks") -# 新增兴趣评估间隔 -INTEREST_EVAL_INTERVAL_SECONDS = 5 -# 新增聊天超时检查间隔 -NORMAL_CHAT_TIMEOUT_CHECK_INTERVAL_SECONDS = 60 -# 新增状态评估间隔 -HF_JUDGE_STATE_UPDATE_INTERVAL_SECONDS = 20 + + # 新增私聊激活检查间隔 PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS = 5 # 与兴趣评估类似,设为5秒 CLEANUP_INTERVAL_SECONDS = 1200 -STATE_UPDATE_INTERVAL_SECONDS = 60 -LOG_INTERVAL_SECONDS = 3 async def _run_periodic_loop( @@ -55,19 +48,13 @@ class BackgroundTaskManager: def __init__( self, - mai_state_info: MaiStateInfo, # Needs current state info - mai_state_manager: MaiStateManager, subheartflow_manager: SubHeartflowManager, ): - self.mai_state_info = mai_state_info - self.mai_state_manager = mai_state_manager self.subheartflow_manager = subheartflow_manager # Task references - self._state_update_task: Optional[asyncio.Task] = None self._cleanup_task: Optional[asyncio.Task] = None self._hf_judge_state_update_task: Optional[asyncio.Task] = None - self._into_focus_task: Optional[asyncio.Task] = None self._private_chat_activation_task: Optional[asyncio.Task] = None # 新增私聊激活任务引用 self._tasks: List[Optional[asyncio.Task]] = [] # Keep track of all tasks @@ -80,15 +67,7 @@ class BackgroundTaskManager: - 将任务引用保存到任务列表 """ - # 任务配置列表: (任务函数, 任务名称, 日志级别, 额外日志信息, 任务对象引用属性名) - task_configs = [ - ( - lambda: self._run_state_update_cycle(STATE_UPDATE_INTERVAL_SECONDS), - "debug", - f"聊天状态更新任务已启动 间隔:{STATE_UPDATE_INTERVAL_SECONDS}s", - "_state_update_task", - ), - ] + task_configs = [] # 根据 chat_mode 条件添加其他任务 if not (global_config.chat.chat_mode == "normal"): @@ -108,12 +87,6 @@ class BackgroundTaskManager: f"私聊激活检查任务已启动 间隔:{PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS}s", "_private_chat_activation_task", ), - # ( - # self._run_into_focus_cycle, - # "debug", # 设为debug,避免过多日志 - # f"专注评估任务已启动 间隔:{INTEREST_EVAL_INTERVAL_SECONDS}s", - # "_into_focus_task", - # ) ] ) else: @@ -163,33 +136,9 @@ class BackgroundTaskManager: # 第三步:清空任务列表 self._tasks = [] # 重置任务列表 - async def _perform_state_update_work(self): - """执行状态更新工作""" - previous_status = self.mai_state_info.get_current_state() - next_state = self.mai_state_manager.check_and_decide_next_state(self.mai_state_info) - - state_changed = False - - if next_state is not None: - state_changed = self.mai_state_info.update_mai_status(next_state) - - # 处理保持离线状态的特殊情况 - if not state_changed and next_state == previous_status == self.mai_state_info.mai_status.OFFLINE: - self.mai_state_info.reset_state_timer() - logger.debug("[后台任务] 保持离线状态并重置计时器") - state_changed = True # 触发后续处理 - - if state_changed: - current_state = self.mai_state_info.get_current_state() - # 状态转换处理 - if ( - current_state == self.mai_state_info.mai_status.OFFLINE - and previous_status != self.mai_state_info.mai_status.OFFLINE - ): - logger.info("检测到离线,停用所有子心流") - await self.subheartflow_manager.deactivate_all_subflows() + async def _perform_cleanup_work(self): """执行子心流清理任务 @@ -216,27 +165,12 @@ class BackgroundTaskManager: # 记录最终清理结果 logger.info(f"[清理任务] 清理完成, 共停止 {stopped_count}/{len(flows_to_stop)} 个子心流") - # --- 新增兴趣评估工作函数 --- - # async def _perform_into_focus_work(self): - # """执行一轮子心流兴趣评估与提升检查。""" - # # 直接调用 subheartflow_manager 的方法,并传递当前状态信息 - # await self.subheartflow_manager.sbhf_normal_into_focus() - - async def _run_state_update_cycle(self, interval: int): - await _run_periodic_loop(task_name="State Update", interval=interval, task_func=self._perform_state_update_work) async def _run_cleanup_cycle(self): await _run_periodic_loop( task_name="Subflow Cleanup", interval=CLEANUP_INTERVAL_SECONDS, task_func=self._perform_cleanup_work ) - # --- 新增兴趣评估任务运行器 --- - # async def _run_into_focus_cycle(self): - # await _run_periodic_loop( - # task_name="Into Focus", - # interval=INTEREST_EVAL_INTERVAL_SECONDS, - # task_func=self._perform_into_focus_work, - # ) # 新增私聊激活任务运行器 async def _run_private_chat_activation_cycle(self, interval: int): diff --git a/src/chat/heart_flow/heartflow.py b/src/chat/heart_flow/heartflow.py index e1f8d9570..7e12135ad 100644 --- a/src/chat/heart_flow/heartflow.py +++ b/src/chat/heart_flow/heartflow.py @@ -1,7 +1,6 @@ from src.chat.heart_flow.sub_heartflow import SubHeartflow, ChatState from src.common.logger_manager import get_logger from typing import Any, Optional, List -from src.chat.heart_flow.mai_state_manager import MaiStateInfo, MaiStateManager from src.chat.heart_flow.subheartflow_manager import SubHeartflowManager from src.chat.heart_flow.background_tasks import BackgroundTaskManager # Import BackgroundTaskManager @@ -16,17 +15,12 @@ class Heartflow: """ def __init__(self): - # 状态管理相关 - self.current_state: MaiStateInfo = MaiStateInfo() # 当前状态信息 - self.mai_state_manager: MaiStateManager = MaiStateManager() # 状态决策管理器 # 子心流管理 (在初始化时传入 current_state) - self.subheartflow_manager: SubHeartflowManager = SubHeartflowManager(self.current_state) + self.subheartflow_manager: SubHeartflowManager = SubHeartflowManager() # 后台任务管理器 (整合所有定时任务) self.background_task_manager: BackgroundTaskManager = BackgroundTaskManager( - mai_state_info=self.current_state, - mai_state_manager=self.mai_state_manager, subheartflow_manager=self.subheartflow_manager, ) diff --git a/src/chat/heart_flow/mai_state_manager.py b/src/chat/heart_flow/mai_state_manager.py deleted file mode 100644 index 81f03dec7..000000000 --- a/src/chat/heart_flow/mai_state_manager.py +++ /dev/null @@ -1,135 +0,0 @@ -import enum -import time -import random -from typing import List, Tuple, Optional -from src.common.logger_manager import get_logger -from src.manager.mood_manager import mood_manager - -logger = get_logger("mai_state") - - -class MaiState(enum.Enum): - """ - 聊天状态: - OFFLINE: 不在线:回复概率极低,不会进行任何聊天 - NORMAL_CHAT: 正常看手机:回复概率较高,会进行一些普通聊天和少量的专注聊天 - FOCUSED_CHAT: 专注聊天:回复概率极高,会进行专注聊天和少量的普通聊天 - """ - - OFFLINE = "不在线" - NORMAL_CHAT = "正常看手机" - FOCUSED_CHAT = "专心看手机" - - -class MaiStateInfo: - def __init__(self): - self.mai_status: MaiState = MaiState.NORMAL_CHAT # 初始状态改为 NORMAL_CHAT - self.mai_status_history: List[Tuple[MaiState, float]] = [] # 历史状态,包含 状态,时间戳 - self.last_status_change_time: float = time.time() # 状态最后改变时间 - self.last_min_check_time: float = time.time() # 上次1分钟规则检查时间 - - # Mood management is now part of MaiStateInfo - self.mood_manager = mood_manager # Use singleton instance - - def update_mai_status(self, new_status: MaiState) -> bool: - """ - 更新聊天状态。 - - Args: - new_status: 新的 MaiState 状态。 - - Returns: - bool: 如果状态实际发生了改变则返回 True,否则返回 False。 - """ - if new_status != self.mai_status: - self.mai_status = new_status - current_time = time.time() - self.last_status_change_time = current_time - self.last_min_check_time = current_time # Reset 1-min check on any state change - self.mai_status_history.append((new_status, current_time)) - logger.info(f"麦麦状态更新为: {self.mai_status.value}") - return True - else: - return False - - def reset_state_timer(self): - """ - 重置状态持续时间计时器和一分钟规则检查计时器。 - 通常在状态保持不变但需要重新开始计时的情况下调用(例如,保持 OFFLINE)。 - """ - current_time = time.time() - self.last_status_change_time = current_time - self.last_min_check_time = current_time # Also reset the 1-min check timer - logger.debug("MaiStateInfo 状态计时器已重置。") - - def get_mood_prompt(self) -> str: - """获取当前的心情提示词""" - # Delegate to the internal mood manager - return self.mood_manager.get_mood_prompt() - - def get_current_state(self) -> MaiState: - """获取当前的 MaiState""" - return self.mai_status - - -class MaiStateManager: - """管理 Mai 的整体状态转换逻辑""" - - def __init__(self): - pass - - @staticmethod - def check_and_decide_next_state(current_state_info: MaiStateInfo) -> Optional[MaiState]: - """ - 根据当前状态和规则检查是否需要转换状态,并决定下一个状态。 - """ - current_time = time.time() - current_status = current_state_info.mai_status - time_in_current_status = current_time - current_state_info.last_status_change_time - next_state: Optional[MaiState] = None - - def _resolve_offline(candidate_state: MaiState) -> MaiState: - if candidate_state == MaiState.OFFLINE: - return current_status - return candidate_state - - if current_status == MaiState.OFFLINE: - logger.info("当前[离线],没看手机,思考要不要上线看看......") - elif current_status == MaiState.NORMAL_CHAT: - logger.info("当前在[正常看手机]思考要不要继续聊下去......") - elif current_status == MaiState.FOCUSED_CHAT: - logger.info("当前在[专心看手机]思考要不要继续聊下去......") - - if next_state is None: - time_limit_exceeded = False - choices_list = [] - weights = [] - rule_id = "" - - if current_status == MaiState.OFFLINE: - return None - elif current_status == MaiState.NORMAL_CHAT: - if time_in_current_status >= 300: # NORMAL_CHAT 最多持续 300 秒 - time_limit_exceeded = True - rule_id = "2.3 (From NORMAL_CHAT)" - weights = [100] - choices_list = [MaiState.FOCUSED_CHAT] - elif current_status == MaiState.FOCUSED_CHAT: - if time_in_current_status >= 600: # FOCUSED_CHAT 最多持续 600 秒 - time_limit_exceeded = True - rule_id = "2.4 (From FOCUSED_CHAT)" - weights = [100] - choices_list = [MaiState.NORMAL_CHAT] - - if time_limit_exceeded: - next_state_candidate = random.choices(choices_list, weights=weights, k=1)[0] - resolved_candidate = _resolve_offline(next_state_candidate) - logger.debug( - f"规则{rule_id}:时间到,切换到 {next_state_candidate.value},resolve 为 {resolved_candidate.value}" - ) - next_state = resolved_candidate - - if next_state is not None and next_state != current_status: - return next_state - else: - return None diff --git a/src/chat/heart_flow/sub_heartflow.py b/src/chat/heart_flow/sub_heartflow.py index 0d4ac281a..b7267bdc1 100644 --- a/src/chat/heart_flow/sub_heartflow.py +++ b/src/chat/heart_flow/sub_heartflow.py @@ -9,7 +9,6 @@ from src.chat.message_receive.message import MessageRecv from src.chat.message_receive.chat_stream import chat_manager from src.chat.focus_chat.heartFC_chat import HeartFChatting from src.chat.normal_chat.normal_chat import NormalChat -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 src.config.config import global_config @@ -23,7 +22,6 @@ class SubHeartflow: def __init__( self, subheartflow_id, - mai_states: MaiStateInfo, ): """子心流初始化函数 @@ -36,9 +34,6 @@ class SubHeartflow: self.subheartflow_id = subheartflow_id self.chat_id = subheartflow_id - # 麦麦的状态 - self.mai_states = mai_states - # 这个聊天流的状态 self.chat_state: ChatStateInfo = ChatStateInfo() self.chat_state_changed_time: float = time.time() @@ -334,10 +329,10 @@ class SubHeartflow: return self.normal_chat_instance.get_recent_replies(limit) return [] - def add_interest_message(self, message: MessageRecv, interest_value: float, is_mentioned: bool): + def add_message_to_normal_chat_cache(self, message: MessageRecv, interest_value: float, is_mentioned: bool): self.interest_dict[message.message_info.message_id] = (message, interest_value, is_mentioned) # 如果字典长度超过10,删除最旧的消息 - if len(self.interest_dict) > 10: + if len(self.interest_dict) > 30: oldest_key = next(iter(self.interest_dict)) self.interest_dict.pop(oldest_key) diff --git a/src/chat/heart_flow/subheartflow_manager.py b/src/chat/heart_flow/subheartflow_manager.py index e3e68f55d..bad4393c9 100644 --- a/src/chat/heart_flow/subheartflow_manager.py +++ b/src/chat/heart_flow/subheartflow_manager.py @@ -4,7 +4,6 @@ from typing import Dict, Any, Optional, List from src.common.logger_manager import get_logger from src.chat.message_receive.chat_stream import chat_manager from src.chat.heart_flow.sub_heartflow import SubHeartflow, ChatState -from src.chat.heart_flow.mai_state_manager import MaiStateInfo from src.chat.heart_flow.observation.chatting_observation import ChattingObservation @@ -54,10 +53,9 @@ async def _try_set_subflow_absent_internal(subflow: "SubHeartflow", log_prefix: class SubHeartflowManager: """管理所有活跃的 SubHeartflow 实例。""" - def __init__(self, mai_state_info: MaiStateInfo): + def __init__(self): self.subheartflows: Dict[Any, "SubHeartflow"] = {} self._lock = asyncio.Lock() # 用于保护 self.subheartflows 的访问 - self.mai_state_info: MaiStateInfo = mai_state_info # 存储传入的 MaiStateInfo 实例 async def force_change_state(self, subflow_id: Any, target_state: ChatState) -> bool: """强制改变指定子心流的状态""" @@ -97,7 +95,6 @@ class SubHeartflowManager: # 初始化子心流, 传入 mai_state_info new_subflow = SubHeartflow( subheartflow_id, - self.mai_state_info, ) # 首先创建并添加聊天观察者 diff --git a/src/chat/normal_chat/normal_chat.py b/src/chat/normal_chat/normal_chat.py index 67bc1ab44..cb78c7016 100644 --- a/src/chat/normal_chat/normal_chat.py +++ b/src/chat/normal_chat/normal_chat.py @@ -1,12 +1,9 @@ import asyncio -import statistics # 导入 statistics 模块 import time import traceback from random import random from typing import List, Optional # 导入 Optional - from maim_message import UserInfo, Seg - from src.common.logger_manager import get_logger from src.chat.heart_flow.utils_chat import get_chat_type_and_target_info from src.manager.mood_manager import mood_manager @@ -21,6 +18,7 @@ from src.chat.message_receive.message_sender import message_manager from src.chat.utils.utils_image import image_path_to_base64 from src.chat.emoji_system.emoji_manager import emoji_manager from src.chat.normal_chat.willing.willing_manager import willing_manager +from src.chat.normal_chat.normal_chat_utils import get_recent_message_stats from src.config.config import global_config logger = get_logger("normal_chat") @@ -39,6 +37,8 @@ class NormalChat: self.is_group_chat: bool = False self.chat_target_info: Optional[dict] = None + + self.willing_amplifier = 1 # Other sync initializations self.gpt = NormalChatGenerator() @@ -209,10 +209,12 @@ class NormalChat: for msg_id, (message, interest_value, is_mentioned) in items_to_process: try: # 处理消息 + self.adjust_reply_frequency() + await self.normal_response( message=message, is_mentioned=is_mentioned, - interested_rate=interest_value, + interested_rate=interest_value * self.willing_amplifier, rewind_response=False, ) except Exception as e: @@ -228,26 +230,18 @@ class NormalChat: if self._disabled: logger.info(f"[{self.stream_name}] 已停用,忽略 normal_response。") return - # 检查收到的消息是否属于当前实例处理的 chat stream - if message.chat_stream.stream_id != self.stream_id: - logger.error( - f"[{self.stream_name}] normal_response 收到不匹配的消息 (来自 {message.chat_stream.stream_id}),预期 {self.stream_id}。已忽略。" - ) - return timing_results = {} - reply_probability = 1.0 if is_mentioned else 0.0 # 如果被提及,基础概率为1,否则需要意愿判断 - + # 意愿管理器:设置当前message信息 - willing_manager.setup(message, self.chat_stream, is_mentioned, interested_rate) # 获取回复概率 - is_willing = False + # is_willing = False # 仅在未被提及或基础概率不为1时查询意愿概率 if reply_probability < 1: # 简化逻辑,如果未提及 (reply_probability 为 0),则获取意愿概率 - is_willing = True + # is_willing = True reply_probability = await willing_manager.get_reply_probability(message.message_info.message_id) if message.message_info.additional_config: @@ -257,13 +251,13 @@ class NormalChat: # 打印消息信息 mes_name = self.chat_stream.group_info.group_name if self.chat_stream.group_info else "私聊" - current_time = time.strftime("%H:%M:%S", time.localtime(message.message_info.time)) + # current_time = time.strftime("%H:%M:%S", time.localtime(message.message_info.time)) # 使用 self.stream_id - willing_log = f"[回复意愿:{await willing_manager.get_willing(self.stream_id):.2f}]" if is_willing else "" + # willing_log = f"[激活值:{await willing_manager.get_willing(self.stream_id):.2f}]" if is_willing else "" logger.info( - f"[{current_time}][{mes_name}]" + f"[{mes_name}]" f"{message.message_info.user_info.user_nickname}:" # 使用 self.chat_stream - f"{message.processed_plain_text}{willing_log}[概率:{reply_probability * 100:.1f}%]" + f"{message.processed_plain_text}[回复概率:{reply_probability * 100:.1f}%]" ) do_reply = False response_set = None # 初始化 response_set @@ -346,16 +340,13 @@ class NormalChat: # 检查是否需要切换到focus模式 await self._check_switch_to_focus() - else: - logger.warning(f"[{self.stream_name}] 思考消息 {thinking_id} 在发送前丢失,无法记录 info_catcher") info_catcher.done_catch() - # 处理表情包 (不再需要传入 chat) with Timer("处理表情包", timing_results): await self._handle_emoji(message, response_set[0]) - # 更新关系情绪 (不再需要传入 chat) + with Timer("关系更新", timing_results): await self._update_relationship(message, response_set) @@ -479,9 +470,6 @@ class NormalChat: # 统计1分钟内的回复数量 recent_reply_count = sum(1 for reply in self.recent_replies if reply["time"] > one_minute_ago) - # print(111111111111111333333333333333333333333331111111111111111111111111111111111) - # print(recent_reply_count) - # 如果1分钟内回复数量大于8,触发切换到focus模式 if recent_reply_count > reply_threshold: logger.info( f"[{self.stream_name}] 检测到1分钟内回复数量({recent_reply_count})大于{reply_threshold},触发切换到focus模式" @@ -491,3 +479,29 @@ class NormalChat: await self.on_switch_to_focus_callback() except Exception as e: logger.error(f"[{self.stream_name}] 触发切换到focus模式时出错: {e}\n{traceback.format_exc()}") + + + def adjust_reply_frequency(self, duration: int = 10): + """ + 调整回复频率 + """ + # 获取最近30分钟内的消息统计 + print(f"willing_amplifier: {self.willing_amplifier}") + stats = get_recent_message_stats(minutes=duration, chat_id=self.stream_id) + bot_reply_count = stats["bot_reply_count"] + print(f"[{self.stream_name}] 最近{duration}分钟内回复数量: {bot_reply_count}") + total_message_count = stats["total_message_count"] + print(f"[{self.stream_name}] 最近{duration}分钟内消息总数: {total_message_count}") + + # 计算回复频率 + _reply_frequency = bot_reply_count / total_message_count + + # 如果回复频率低于0.5,增加回复概率 + if bot_reply_count/duration < global_config.normal_chat.talk_frequency: + # differ = global_config.normal_chat.talk_frequency - reply_frequency + logger.info(f"[{self.stream_name}] 回复频率低于{global_config.normal_chat.talk_frequency},增加回复概率") + self.willing_amplifier += 0.1 + else: + logger.info(f"[{self.stream_name}] 回复频率高于{global_config.normal_chat.talk_frequency},减少回复概率") + self.willing_amplifier -= 0.1 + diff --git a/src/chat/normal_chat/normal_chat_utils.py b/src/chat/normal_chat/normal_chat_utils.py new file mode 100644 index 000000000..2eae48296 --- /dev/null +++ b/src/chat/normal_chat/normal_chat_utils.py @@ -0,0 +1,33 @@ +import time +from src.config.config import global_config +from src.common.message_repository import count_messages + + +def get_recent_message_stats(minutes: int = 30, chat_id: str = None) -> dict: + """ + Args: + minutes (int): 检索的分钟数,默认30分钟 + chat_id (str, optional): 指定的chat_id,仅统计该chat下的消息。为None时统计全部。 + Returns: + dict: {"bot_reply_count": int, "total_message_count": int} + """ + + now = time.time() + start_time = now - minutes * 60 + bot_id = global_config.bot.qq_account + + filter_base = {"time": {"$gte": start_time}} + if chat_id is not None: + filter_base["chat_id"] = chat_id + + # 总消息数 + total_message_count = count_messages(filter_base) + # bot自身回复数 + bot_filter = filter_base.copy() + bot_filter["user_id"] = bot_id + bot_reply_count = count_messages(bot_filter) + + return { + "bot_reply_count": bot_reply_count, + "total_message_count": total_message_count + } \ No newline at end of file diff --git a/src/common/logger.py b/src/common/logger.py index 3ed0fd7f9..7258d6193 100644 --- a/src/common/logger.py +++ b/src/common/logger.py @@ -271,7 +271,7 @@ CHAT_STYLE_CONFIG = { "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 见闻 | {message}", }, "simple": { - "console_format": "{time:HH:mm:ss} | 见闻 | {message}", # noqa: E501 + "console_format": "{time:HH:mm:ss} | 见闻 | {message}", # noqa: E501 "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 见闻 | {message}", }, } @@ -288,7 +288,7 @@ NORMAL_CHAT_STYLE_CONFIG = { "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 一般水群 | {message}", }, "simple": { - "console_format": "{time:HH:mm:ss} | 一般水群 | {message}", # noqa: E501 + "console_format": "{time:HH:mm:ss} | 一般水群 | {message}", # noqa: E501 "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 一般水群 | {message}", }, } diff --git a/src/config/official_configs.py b/src/config/official_configs.py index 5e5199da4..e353500fd 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -91,7 +91,7 @@ class NormalChatConfig(ConfigBase): max_context_size: int = 15 """上下文长度""" - message_buffer: bool = True + message_buffer: bool = False """消息缓冲器""" emoji_chance: float = 0.2 @@ -103,6 +103,9 @@ class NormalChatConfig(ConfigBase): willing_mode: str = "classical" """意愿模式""" + talk_frequency: float = 1 + """回复频率阈值""" + response_willing_amplifier: float = 1.0 """回复意愿放大系数""" diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index c78633408..946e3374f 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -1,5 +1,5 @@ [inner] -version = "2.5.0" +version = "2.6.0" #----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读---- #如果你想要修改配置文件,请在修改后将version的值进行变更 @@ -18,22 +18,24 @@ nickname = "麦麦" alias_names = ["麦叠", "牢麦"] #仅在 专注聊天 有效 [personality] -personality_core = "是一个积极向上的女大学生" # 建议20字以内,谁再写3000字小作文敲谁脑袋 +personality_core = "是一个积极向上的女大学生" # 建议50字以内 personality_sides = [ "用一句话或几句话描述人格的一些细节", "用一句话或几句话描述人格的一些细节", "用一句话或几句话描述人格的一些细节", -]# 条数任意,不能为0 +] +# 条数任意,不能为0 # 身份特点 -[identity] #アイデンティティがない 生まれないらららら +#アイデンティティがない 生まれないらららら +[identity] identity_detail = [ "年龄为19岁", "是女孩子", "身高为160cm", "有橙色的短发", ] -# 可以描述外贸,性别,身高,职业,属性等等描述 +# 可以描述外貌,性别,身高,职业,属性等等描述 # 条数任意,不能为0 [relationship] @@ -69,15 +71,18 @@ normal_chat_first_probability = 0.3 # 麦麦回答时选择首要模型的概率 max_context_size = 15 #上下文长度 emoji_chance = 0.2 # 麦麦一般回复时使用表情包的概率,设置为1让麦麦自己决定发不发 thinking_timeout = 120 # 麦麦最长思考时间,超过这个时间的思考会放弃(往往是api反应太慢) -message_buffer = true # 启用消息缓冲器?启用此项以解决消息的拆分问题,但会使麦麦的回复延迟 willing_mode = "classical" # 回复意愿模式 —— 经典模式:classical,mxp模式:mxp,自定义模式:custom(需要你自己实现) +talk_frequency = 1 # 麦麦回复频率,一般为1,默认频率下,30分钟麦麦回复30条(约数) + response_willing_amplifier = 1 # 麦麦回复意愿放大系数,一般为1 response_interested_rate_amplifier = 1 # 麦麦回复兴趣度放大系数,听到记忆里的内容时放大系数 -down_frequency_rate = 3 # 降低回复频率的群组回复意愿降低系数 除法 + emoji_response_penalty = 0 # 表情包回复惩罚系数,设为0为不回复单个表情包,减少单独回复表情包的概率 mentioned_bot_inevitable_reply = false # 提及 bot 必然回复 at_bot_inevitable_reply = false # @bot 必然回复 + +down_frequency_rate = 3 # 降低回复频率的群组回复意愿降低系数 除法 talk_frequency_down_groups = [] #降低回复频率的群号码 [focus_chat] #专注聊天 @@ -163,26 +168,8 @@ max_length = 256 # 回复允许的最大长度 max_sentence_num = 4 # 回复允许的最大句子数 enable_kaomoji_protection = false # 是否启用颜文字保护 -[maim_message] -auth_token = [] # 认证令牌,用于API验证,为空则不启用验证 -# 以下项目若要使用需要打开use_custom,并单独配置maim_message的服务器 -use_custom = false # 是否启用自定义的maim_message服务器,注意这需要设置新的端口,不能与.env重复 -host="127.0.0.1" -port=8090 -mode="ws" # 支持ws和tcp两种模式 -use_wss = false # 是否使用WSS安全连接,只支持ws模式 -cert_file = "" # SSL证书文件路径,仅在use_wss=true时有效 -key_file = "" # SSL密钥文件路径,仅在use_wss=true时有效 -[telemetry] #发送统计信息,主要是看全球有多少只麦麦 -enable = true - -[experimental] #实验性功能 -debug_show_chat_mode = true # 是否在回复后显示当前聊天模式 -enable_friend_chat = false # 是否启用好友聊天 -pfc_chatting = false # 是否启用PFC聊天,该功能仅作用于私聊,与回复模式独立,在0.7.0暂时无效 - #下面的模型若使用硅基流动则不需要更改,使用ds官方则改成.env自定义的宏,使用自定义模型则选择定位相似的模型自己填写 # stream = : 用于指定模型是否是使用流式输出 @@ -333,5 +320,24 @@ pri_out = 8 +[maim_message] +auth_token = [] # 认证令牌,用于API验证,为空则不启用验证 +# 以下项目若要使用需要打开use_custom,并单独配置maim_message的服务器 +use_custom = false # 是否启用自定义的maim_message服务器,注意这需要设置新的端口,不能与.env重复 +host="127.0.0.1" +port=8090 +mode="ws" # 支持ws和tcp两种模式 +use_wss = false # 是否使用WSS安全连接,只支持ws模式 +cert_file = "" # SSL证书文件路径,仅在use_wss=true时有效 +key_file = "" # SSL密钥文件路径,仅在use_wss=true时有效 + +[telemetry] #发送统计信息,主要是看全球有多少只麦麦 +enable = true + +[experimental] #实验性功能 +debug_show_chat_mode = true # 是否在回复后显示当前聊天模式 +enable_friend_chat = false # 是否启用好友聊天 +pfc_chatting = false # 暂时无效 + From 218d0d4a5dfe1948e3d494a83b413b68f4ba0a1b Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Wed, 28 May 2025 20:44:26 +0800 Subject: [PATCH 2/3] pass ruff --- .../expressors/default_expressor.py | 19 ++++++++--------- src/chat/focus_chat/heartFC_chat.py | 4 +++- .../focus_chat/heartflow_message_processor.py | 13 ++++-------- src/chat/heart_flow/background_tasks.py | 8 +------ src/chat/heart_flow/heartflow.py | 1 - src/chat/heart_flow/sub_heartflow.py | 1 + src/chat/message_receive/storage.py | 2 +- src/chat/normal_chat/normal_chat.py | 21 +++++++------------ src/chat/normal_chat/normal_chat_generator.py | 10 ++++----- src/chat/normal_chat/normal_chat_utils.py | 5 +---- src/chat/normal_chat/normal_prompt.py | 1 - src/chat/utils/chat_message_builder.py | 5 +++-- src/config/official_configs.py | 6 ++---- src/plugins/test_plugin/actions/__init__.py | 1 + .../test_plugin/actions/mute_action.py | 9 ++++---- template/bot_config_template.toml | 2 +- 16 files changed, 45 insertions(+), 63 deletions(-) diff --git a/src/chat/focus_chat/expressors/default_expressor.py b/src/chat/focus_chat/expressors/default_expressor.py index cbea0a22d..382d20aad 100644 --- a/src/chat/focus_chat/expressors/default_expressor.py +++ b/src/chat/focus_chat/expressors/default_expressor.py @@ -16,7 +16,6 @@ from src.chat.utils.info_catcher import info_catcher_manager from src.chat.heart_flow.utils_chat import get_chat_type_and_target_info from src.chat.message_receive.chat_stream import ChatStream from src.chat.focus_chat.hfc_utils import parse_thinking_id_to_timestamp -from src.individuality.individuality import individuality from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat import time @@ -106,10 +105,7 @@ class DefaultExpressor: user_nickname=global_config.bot.nickname, platform=messageinfo.platform, ) - # logger.debug(f"创建思考消息:{anchor_message}") - # logger.debug(f"创建思考消息chat:{chat}") - # logger.debug(f"创建思考消息bot_user_info:{bot_user_info}") - # logger.debug(f"创建思考消息messageinfo:{messageinfo}") + thinking_message = MessageThinking( message_id=thinking_id, chat_stream=chat, @@ -281,14 +277,14 @@ class DefaultExpressor: in_mind_reply, target_message, ) -> str: - prompt_personality = individuality.get_prompt(x_person=0, level=2) + # prompt_personality = individuality.get_prompt(x_person=0, level=2) # Determine if it's a group chat is_group_chat = bool(chat_stream.group_info) # Use sender_name passed from caller for private chat, otherwise use a default for group # Default sender_name for group chat isn't used in the group prompt template, but set for consistency - effective_sender_name = sender_name if not is_group_chat else "某人" + # effective_sender_name = sender_name if not is_group_chat else "某人" message_list_before_now = get_raw_msg_before_timestamp_with_chat( chat_id=chat_stream.stream_id, @@ -377,7 +373,11 @@ class DefaultExpressor: # --- 发送器 (Sender) --- # async def send_response_messages( - self, anchor_message: Optional[MessageRecv], response_set: List[Tuple[str, str]], thinking_id: str = "", display_message: str = "" + self, + anchor_message: Optional[MessageRecv], + response_set: List[Tuple[str, str]], + thinking_id: str = "", + display_message: str = "", ) -> Optional[MessageSending]: """发送回复消息 (尝试锚定到 anchor_message),使用 HeartFCSender""" chat = self.chat_stream @@ -412,10 +412,9 @@ class DefaultExpressor: # 为每个消息片段生成唯一ID type = msg_text[0] data = msg_text[1] - + if global_config.experimental.debug_show_chat_mode and type == "text": data += "ᶠ" - part_message_id = f"{thinking_id}_{i}" message_segment = Seg(type=type, data=data) diff --git a/src/chat/focus_chat/heartFC_chat.py b/src/chat/focus_chat/heartFC_chat.py index ab061d85b..63ce5c30d 100644 --- a/src/chat/focus_chat/heartFC_chat.py +++ b/src/chat/focus_chat/heartFC_chat.py @@ -379,12 +379,14 @@ class HeartFChatting: for processor in self.processors: processor_name = processor.__class__.log_prefix + # 用lambda包裹,便于传参 async def run_with_timeout(proc=processor): return await asyncio.wait_for( proc.process_info(observations=observations, running_memorys=running_memorys), - timeout=PROCESSOR_TIMEOUT + timeout=PROCESSOR_TIMEOUT, ) + task = asyncio.create_task(run_with_timeout()) processor_tasks.append(task) task_to_name_map[task] = processor_name diff --git a/src/chat/focus_chat/heartflow_message_processor.py b/src/chat/focus_chat/heartflow_message_processor.py index 18349d7ab..8277e69f9 100644 --- a/src/chat/focus_chat/heartflow_message_processor.py +++ b/src/chat/focus_chat/heartflow_message_processor.py @@ -1,4 +1,3 @@ -import time import traceback from ..memory_system.Hippocampus import HippocampusManager from ...config.config import global_config @@ -73,12 +72,12 @@ async def _calculate_interest(message: MessageRecv) -> Tuple[float, bool]: text_len = len(message.processed_plain_text) # 根据文本长度调整兴趣度,长度越大兴趣度越高,但增长率递减,最低0.01,最高0.05 # 采用对数函数实现递减增长 - + base_interest = 0.01 + (0.05 - 0.01) * (math.log10(text_len + 1) / math.log10(1000 + 1)) base_interest = min(max(base_interest, 0.01), 0.05) - + interested_rate += base_interest - + logger.trace(f"记忆激活率: {interested_rate:.2f}") if is_mentioned: @@ -220,11 +219,7 @@ class HeartFCMessageReceiver: # 7. 日志记录 mes_name = chat.group_info.group_name if chat.group_info else "私聊" # current_time = time.strftime("%H:%M:%S", time.localtime(message.message_info.time)) - logger.info( - f"[{mes_name}]" - f"{userinfo.user_nickname}:" - f"{message.processed_plain_text}" - ) + logger.info(f"[{mes_name}]{userinfo.user_nickname}:{message.processed_plain_text}") # 8. 关系处理 if global_config.relationship.give_name: diff --git a/src/chat/heart_flow/background_tasks.py b/src/chat/heart_flow/background_tasks.py index db2604567..4bacfd0a0 100644 --- a/src/chat/heart_flow/background_tasks.py +++ b/src/chat/heart_flow/background_tasks.py @@ -8,8 +8,6 @@ from src.config.config import global_config logger = get_logger("background_tasks") - - # 新增私聊激活检查间隔 PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS = 5 # 与兴趣评估类似,设为5秒 @@ -136,9 +134,7 @@ class BackgroundTaskManager: # 第三步:清空任务列表 self._tasks = [] # 重置任务列表 - # 状态转换处理 - - + # 状态转换处理 async def _perform_cleanup_work(self): """执行子心流清理任务 @@ -165,13 +161,11 @@ class BackgroundTaskManager: # 记录最终清理结果 logger.info(f"[清理任务] 清理完成, 共停止 {stopped_count}/{len(flows_to_stop)} 个子心流") - async def _run_cleanup_cycle(self): await _run_periodic_loop( task_name="Subflow Cleanup", interval=CLEANUP_INTERVAL_SECONDS, task_func=self._perform_cleanup_work ) - # 新增私聊激活任务运行器 async def _run_private_chat_activation_cycle(self, interval: int): await _run_periodic_loop( diff --git a/src/chat/heart_flow/heartflow.py b/src/chat/heart_flow/heartflow.py index 7e12135ad..d58c5cde2 100644 --- a/src/chat/heart_flow/heartflow.py +++ b/src/chat/heart_flow/heartflow.py @@ -15,7 +15,6 @@ class Heartflow: """ def __init__(self): - # 子心流管理 (在初始化时传入 current_state) self.subheartflow_manager: SubHeartflowManager = SubHeartflowManager() diff --git a/src/chat/heart_flow/sub_heartflow.py b/src/chat/heart_flow/sub_heartflow.py index b7267bdc1..c95f606b1 100644 --- a/src/chat/heart_flow/sub_heartflow.py +++ b/src/chat/heart_flow/sub_heartflow.py @@ -18,6 +18,7 @@ logger = get_logger("sub_heartflow") install(extra_lines=3) + class SubHeartflow: def __init__( self, diff --git a/src/chat/message_receive/storage.py b/src/chat/message_receive/storage.py index 54dd68f03..8c05a9ab0 100644 --- a/src/chat/message_receive/storage.py +++ b/src/chat/message_receive/storage.py @@ -24,7 +24,7 @@ class MessageStorage: else: filtered_processed_plain_text = "" - if isinstance(message,MessageSending): + if isinstance(message, MessageSending): display_message = message.display_message if display_message: filtered_display_message = re.sub(pattern, "", display_message, flags=re.DOTALL) diff --git a/src/chat/normal_chat/normal_chat.py b/src/chat/normal_chat/normal_chat.py index cb78c7016..984781834 100644 --- a/src/chat/normal_chat/normal_chat.py +++ b/src/chat/normal_chat/normal_chat.py @@ -37,7 +37,7 @@ class NormalChat: self.is_group_chat: bool = False self.chat_target_info: Optional[dict] = None - + self.willing_amplifier = 1 # Other sync initializations @@ -56,7 +56,6 @@ class NormalChat: self._disabled = False # 增加停用标志 - async def initialize(self): """异步初始化,获取聊天类型和目标信息。""" if self._initialized: @@ -210,7 +209,7 @@ class NormalChat: try: # 处理消息 self.adjust_reply_frequency() - + await self.normal_response( message=message, is_mentioned=is_mentioned, @@ -233,7 +232,7 @@ class NormalChat: timing_results = {} reply_probability = 1.0 if is_mentioned else 0.0 # 如果被提及,基础概率为1,否则需要意愿判断 - + # 意愿管理器:设置当前message信息 willing_manager.setup(message, self.chat_stream, is_mentioned, interested_rate) @@ -306,7 +305,7 @@ class NormalChat: return # 不执行后续步骤 logger.info(f"[{self.stream_name}] 回复内容: {response_set}") - + if self._disabled: logger.info(f"[{self.stream_name}] 已停用,忽略 normal_response。") return @@ -340,13 +339,11 @@ class NormalChat: # 检查是否需要切换到focus模式 await self._check_switch_to_focus() - info_catcher.done_catch() with Timer("处理表情包", timing_results): await self._handle_emoji(message, response_set[0]) - with Timer("关系更新", timing_results): await self._update_relationship(message, response_set) @@ -479,8 +476,7 @@ class NormalChat: await self.on_switch_to_focus_callback() except Exception as e: logger.error(f"[{self.stream_name}] 触发切换到focus模式时出错: {e}\n{traceback.format_exc()}") - - + def adjust_reply_frequency(self, duration: int = 10): """ 调整回复频率 @@ -492,16 +488,15 @@ class NormalChat: print(f"[{self.stream_name}] 最近{duration}分钟内回复数量: {bot_reply_count}") total_message_count = stats["total_message_count"] print(f"[{self.stream_name}] 最近{duration}分钟内消息总数: {total_message_count}") - + # 计算回复频率 _reply_frequency = bot_reply_count / total_message_count - + # 如果回复频率低于0.5,增加回复概率 - if bot_reply_count/duration < global_config.normal_chat.talk_frequency: + if bot_reply_count / duration < global_config.normal_chat.talk_frequency: # differ = global_config.normal_chat.talk_frequency - reply_frequency logger.info(f"[{self.stream_name}] 回复频率低于{global_config.normal_chat.talk_frequency},增加回复概率") self.willing_amplifier += 0.1 else: logger.info(f"[{self.stream_name}] 回复频率高于{global_config.normal_chat.talk_frequency},减少回复概率") self.willing_amplifier -= 0.1 - diff --git a/src/chat/normal_chat/normal_chat_generator.py b/src/chat/normal_chat/normal_chat_generator.py index e0a88b4ed..2ad1a1975 100644 --- a/src/chat/normal_chat/normal_chat_generator.py +++ b/src/chat/normal_chat/normal_chat_generator.py @@ -64,11 +64,12 @@ class NormalChatGenerator: async def _generate_response_with_model(self, message: MessageThinking, model: LLMRequest, thinking_id: str): info_catcher = info_catcher_manager.get_info_catcher(thinking_id) + person_id = person_info_manager.get_person_id( + message.chat_stream.user_info.platform, message.chat_stream.user_info.user_id + ) - person_id = person_info_manager.get_person_id(message.chat_stream.user_info.platform, message.chat_stream.user_info.user_id) - person_name = await person_info_manager.get_value(person_id, "person_name") - + if message.chat_stream.user_info.user_cardname and message.chat_stream.user_info.user_nickname: sender_name = ( f"[{message.chat_stream.user_info.user_nickname}]" @@ -78,8 +79,7 @@ class NormalChatGenerator: sender_name = f"[{message.chat_stream.user_info.user_nickname}](你叫ta{person_name})" else: sender_name = f"用户({message.chat_stream.user_info.user_id})" - - + # 构建prompt with Timer() as t_build_prompt: prompt = await prompt_builder.build_prompt( diff --git a/src/chat/normal_chat/normal_chat_utils.py b/src/chat/normal_chat/normal_chat_utils.py index 2eae48296..2ebd3bdaa 100644 --- a/src/chat/normal_chat/normal_chat_utils.py +++ b/src/chat/normal_chat/normal_chat_utils.py @@ -27,7 +27,4 @@ def get_recent_message_stats(minutes: int = 30, chat_id: str = None) -> dict: bot_filter["user_id"] = bot_id bot_reply_count = count_messages(bot_filter) - return { - "bot_reply_count": bot_reply_count, - "total_message_count": total_message_count - } \ No newline at end of file + return {"bot_reply_count": bot_reply_count, "total_message_count": total_message_count} diff --git a/src/chat/normal_chat/normal_prompt.py b/src/chat/normal_chat/normal_prompt.py index 365d42ded..54624a026 100644 --- a/src/chat/normal_chat/normal_prompt.py +++ b/src/chat/normal_chat/normal_prompt.py @@ -17,7 +17,6 @@ logger = get_logger("prompt") def init_prompt(): - Prompt("你正在qq群里聊天,下面是群里在聊的内容:", "chat_target_group1") Prompt("你正在和{sender_name}聊天,这是你们之前聊的内容:", "chat_target_private1") Prompt("在群里聊天", "chat_target_group2") diff --git a/src/chat/utils/chat_message_builder.py b/src/chat/utils/chat_message_builder.py index 38c9e9a84..66b58e257 100644 --- a/src/chat/utils/chat_message_builder.py +++ b/src/chat/utils/chat_message_builder.py @@ -10,6 +10,7 @@ from rich.traceback import install install(extra_lines=3) + def get_raw_msg_by_timestamp( timestamp_start: float, timestamp_end: float, limit: int = 0, limit_mode: str = "latest" ) -> List[Dict[str, Any]]: @@ -198,7 +199,7 @@ async def _build_readable_messages_internal( content = msg.get("display_message") else: content = msg.get("processed_plain_text", "") # 默认空字符串 - + if "ᶠ" in content: content = content.replace("ᶠ", "") if "ⁿ" in content: @@ -465,7 +466,7 @@ async def build_anonymous_messages(messages: List[Dict[str, Any]]) -> str: content = msg.get("display_message") else: content = msg.get("processed_plain_text", "") - + if "ᶠ" in content: content = content.replace("ᶠ", "") if "ⁿ" in content: diff --git a/src/config/official_configs.py b/src/config/official_configs.py index e353500fd..8f98256e9 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -59,7 +59,7 @@ class ChatConfig(ConfigBase): chat_mode: str = "normal" """聊天模式""" - + auto_focus_threshold: float = 1.0 """自动切换到专注聊天的阈值,越低越容易进入专注聊天""" @@ -132,8 +132,6 @@ class NormalChatConfig(ConfigBase): class FocusChatConfig(ConfigBase): """专注聊天配置类""" - - observation_context_size: int = 12 """可观察到的最长上下文大小,超过这个值的上下文会被压缩""" @@ -346,7 +344,7 @@ class TelemetryConfig(ConfigBase): class ExperimentalConfig(ConfigBase): """实验功能配置类""" - debug_show_chat_mode: bool = True + debug_show_chat_mode: bool = False """是否在回复后显示当前聊天模式""" enable_friend_chat: bool = False diff --git a/src/plugins/test_plugin/actions/__init__.py b/src/plugins/test_plugin/actions/__init__.py index 6797e51bf..7d96ea8a4 100644 --- a/src/plugins/test_plugin/actions/__init__.py +++ b/src/plugins/test_plugin/actions/__init__.py @@ -2,5 +2,6 @@ # 导入所有动作模块以确保装饰器被执行 from . import test_action # noqa + # from . import online_action # noqa from . import mute_action # noqa diff --git a/src/plugins/test_plugin/actions/mute_action.py b/src/plugins/test_plugin/actions/mute_action.py index 4f457d900..df112a16d 100644 --- a/src/plugins/test_plugin/actions/mute_action.py +++ b/src/plugins/test_plugin/actions/mute_action.py @@ -57,14 +57,15 @@ class MuteAction(PluginAction): # 确保duration是字符串类型 if int(duration) < 60: duration = 60 - if int(duration) > 3600*24*30: - duration = 3600*24*30 + if int(duration) > 3600 * 24 * 30: + duration = 3600 * 24 * 30 duration_str = str(int(duration)) # 发送群聊禁言命令,按照新格式 await self.send_message( - type = "command", data = {"name": "GROUP_BAN", "args": {"qq_id": str(user_id), "duration": duration_str}}, - display_message = f"我 禁言了 {target} {duration_str}秒" + type="command", + data={"name": "GROUP_BAN", "args": {"qq_id": str(user_id), "duration": duration_str}}, + display_message=f"我 禁言了 {target} {duration_str}秒", ) logger.info(f"{self.log_prefix} 成功发送禁言命令,用户 {target}({user_id}),时长 {duration} 秒") diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index 946e3374f..2d4eccb92 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -335,7 +335,7 @@ key_file = "" # SSL密钥文件路径,仅在use_wss=true时有效 enable = true [experimental] #实验性功能 -debug_show_chat_mode = true # 是否在回复后显示当前聊天模式 +debug_show_chat_mode = false # 是否在回复后显示当前聊天模式 enable_friend_chat = false # 是否启用好友聊天 pfc_chatting = false # 暂时无效 From 859e5201fce76120cb12a303ed770443144ea36f Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Wed, 28 May 2025 20:45:34 +0800 Subject: [PATCH 3/3] Update default_expressor.py --- src/chat/focus_chat/expressors/default_expressor.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/chat/focus_chat/expressors/default_expressor.py b/src/chat/focus_chat/expressors/default_expressor.py index 382d20aad..eceadf670 100644 --- a/src/chat/focus_chat/expressors/default_expressor.py +++ b/src/chat/focus_chat/expressors/default_expressor.py @@ -277,15 +277,8 @@ class DefaultExpressor: in_mind_reply, target_message, ) -> str: - # prompt_personality = individuality.get_prompt(x_person=0, level=2) - - # Determine if it's a group chat is_group_chat = bool(chat_stream.group_info) - # Use sender_name passed from caller for private chat, otherwise use a default for group - # Default sender_name for group chat isn't used in the group prompt template, but set for consistency - # effective_sender_name = sender_name if not is_group_chat else "某人" - message_list_before_now = get_raw_msg_before_timestamp_with_chat( chat_id=chat_stream.stream_id, timestamp=time.time(),