优化no_reply逻辑和参数,适配私聊,解决插空的消息无反应问题

This commit is contained in:
A0000Xz
2025-07-11 19:30:05 +08:00
committed by GitHub
parent 1bff478fcc
commit c87f36973f

View File

@@ -1,5 +1,6 @@
import random import random
import time import time
import asyncio
from typing import Tuple from typing import Tuple
# 导入新插件系统 # 导入新插件系统
@@ -15,6 +16,8 @@ from src.config.config import global_config
logger = get_logger("core_actions") logger = get_logger("core_actions")
#设置一个全局字典确保同一个消息流的下一个NoReplyAction实例能够获取到上一次消息的时间戳
_CHAT_START_TIMES = {}
class NoReplyAction(BaseAction): class NoReplyAction(BaseAction):
"""不回复动作,根据新消息的兴趣值或数量决定何时结束等待. """不回复动作,根据新消息的兴趣值或数量决定何时结束等待.
@@ -39,29 +42,47 @@ class NoReplyAction(BaseAction):
# 新增:兴趣值退出阈值 # 新增:兴趣值退出阈值
_interest_exit_threshold = 3.0 _interest_exit_threshold = 3.0
# 新增:消息数量退出阈值 # 新增:消息数量退出阈值
_min_exit_message_count = 5 _min_exit_message_count = 4
_max_exit_message_count = 10 _max_exit_message_count = 8
# 动作参数定义 # 动作参数定义
action_parameters = {"reason": "不回复的原因"} action_parameters = {"reason": "不回复的原因"}
# 动作使用场景 # 动作使用场景
action_require = ["你发送了消息,目前无人回复"] action_require = [
"你发送了消息,目前无人回复",
"你觉得对方还没把话说完",
"你觉得当前话题不适合插嘴",
"你觉得自己说话太多了"
]
# 关联类型 # 关联类型
associated_types = [] associated_types = []
async def execute(self) -> Tuple[bool, str]: async def execute(self) -> Tuple[bool, str]:
"""执行不回复动作""" """执行不回复动作"""
import asyncio
try: try:
# 获取或初始化当前消息的起始时间因为用户消息是可能在刚决定好可用动作但还没选择动作的时候发送的。原先的start_time设计会导致这种消息被漏掉现在采用全局字典存储
if self.chat_id not in _CHAT_START_TIMES:
# 如果对应消息流没有存储时间,就设置为当前时间
_CHAT_START_TIMES[self.chat_id] = time.time()
start_time = _CHAT_START_TIMES[self.chat_id]
else:
message_current_time = time.time()
if message_current_time - _CHAT_START_TIMES[self.chat_id] > 600:
# 如果上一次NoReplyAction实例记录的最后消息时间戳距离现在时间戳超过了十分钟将会把start_time设置为当前时间戳避免在数据库内过度搜索
start_time = message_current_time
logger.debug("距离上一次消息时间过长,已重置等待开始时间为当前时间")
else:
# 如果距离上一次noreply没有十分钟就沿用上一次noreply退出时记录的最新消息时间戳
start_time = _CHAT_START_TIMES[self.chat_id]
# 增加连续计数 # 增加连续计数
NoReplyAction._consecutive_count += 1 NoReplyAction._consecutive_count += 1
count = NoReplyAction._consecutive_count count = NoReplyAction._consecutive_count
reason = self.action_data.get("reason", "") reason = self.action_data.get("reason", "")
start_time = time.time()
check_interval = 1.0 # 每秒检查一次 check_interval = 1.0 # 每秒检查一次
# 随机生成本次等待需要的新消息数量阈值 # 随机生成本次等待需要的新消息数量阈值
@@ -69,6 +90,9 @@ class NoReplyAction(BaseAction):
logger.info( logger.info(
f"{self.log_prefix} 本次no_reply需要 {exit_message_count_threshold} 条新消息或累计兴趣值超过 {self._interest_exit_threshold} 才能打断" f"{self.log_prefix} 本次no_reply需要 {exit_message_count_threshold} 条新消息或累计兴趣值超过 {self._interest_exit_threshold} 才能打断"
) )
if not self.is_group:
exit_message_count_threshold = 1
logger.info(f"检测到当前环境为私聊本次no_reply已更正为需要{exit_message_count_threshold}条新消息就能打断")
logger.info(f"{self.log_prefix} 选择不回复(第{count}次),开始摸鱼,原因: {reason}") logger.info(f"{self.log_prefix} 选择不回复(第{count}次),开始摸鱼,原因: {reason}")
@@ -77,9 +101,9 @@ class NoReplyAction(BaseAction):
current_time = time.time() current_time = time.time()
elapsed_time = current_time - start_time elapsed_time = current_time - start_time
# 1. 检查新消息 # 1. 检查新消息,默认过滤麦麦自己的消息
recent_messages_dict = message_api.get_messages_by_time_in_chat( recent_messages_dict = message_api.get_messages_by_time_in_chat(
chat_id=self.chat_id, start_time=start_time, end_time=current_time chat_id=self.chat_id, start_time=start_time, end_time=current_time, filter_mai=True
) )
new_message_count = len(recent_messages_dict) new_message_count = len(recent_messages_dict)
@@ -89,11 +113,20 @@ class NoReplyAction(BaseAction):
f"{self.log_prefix} 累计消息数量达到{new_message_count}条(>{exit_message_count_threshold}),结束等待" f"{self.log_prefix} 累计消息数量达到{new_message_count}条(>{exit_message_count_threshold}),结束等待"
) )
exit_reason = f"{global_config.bot.nickname}(你)看到了{new_message_count}条新消息,可以考虑一下是否要进行回复" exit_reason = f"{global_config.bot.nickname}(你)看到了{new_message_count}条新消息,可以考虑一下是否要进行回复"
# 如果是私聊,就稍微改一下退出理由
if not self.is_group:
exit_reason = f"{global_config.bot.nickname}(你)看到了私聊的{new_message_count}条新消息,可以考虑一下是否要进行回复"
await self.store_action_info( await self.store_action_info(
action_build_into_prompt=False, action_build_into_prompt=False,
action_prompt_display=exit_reason, action_prompt_display=exit_reason,
action_done=True, action_done=True,
) )
# 获取最后一条消息
latest_message = recent_messages_dict[-1]
# 在退出时更新全局字典时间戳加1微秒防止重复
_CHAT_START_TIMES[self.chat_id] = latest_message['time'] + 0.000001 # 0.000001秒 = 1微秒
return True, f"累计消息数量达到{new_message_count}条,结束等待 (等待时间: {elapsed_time:.1f}秒)" return True, f"累计消息数量达到{new_message_count}条,结束等待 (等待时间: {elapsed_time:.1f}秒)"
# 3. 检查累计兴趣值 # 3. 检查累计兴趣值
@@ -115,6 +148,12 @@ class NoReplyAction(BaseAction):
action_prompt_display=exit_reason, action_prompt_display=exit_reason,
action_done=True, action_done=True,
) )
# 获取最后一条消息
latest_message = recent_messages_dict[-1]
# 在退出时更新全局字典时间戳加1微秒防止重复
_CHAT_START_TIMES[self.chat_id] = latest_message['time'] + 0.000001 # 0.000001秒 = 1微秒
return ( return (
True, True,
f"累计兴趣值达到{accumulated_interest:.2f},结束等待 (等待时间: {elapsed_time:.1f}秒)", f"累计兴趣值达到{accumulated_interest:.2f},结束等待 (等待时间: {elapsed_time:.1f}秒)",