fix:优化禁言插件,优化表达参数
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [0.8.0] - 2025-1-6
|
## [0.8.0] - 2025-1-6
|
||||||
重大升级!插件系统全面重构,表达方式系统大幅优化
|
重大升级!插件系统全面重构,表达方式系统大幅优化,focus大幅降低token花费和反应速度,加入了人物印象系统,麦麦可以记住群友的特点。支持更精细的分群聊天频率控制,normal模式可以使用planner和action
|
||||||
|
|
||||||
MaiBot 0.8.0 重磅升级!插件系统全面重构,支持更强大的扩展能力;表达方式系统大幅优化,支持智能学习和衰减机制;聊天频率控制更加精细,支持时段化管理;HFC系统性能大幅提升,处理器后置化减少消耗;关系系统升级支持即时构建和人物侧写;日志系统重构使用structlog;大量稳定性修复和性能优化。
|
MaiBot 0.8.0 重磅升级!插件系统全面重构,支持更强大的扩展能力;表达方式系统大幅优化,支持智能学习和衰减机制;聊天频率控制更加精细,支持时段化管理;HFC系统性能大幅提升,处理器后置化减少消耗;关系系统升级支持即时构建和人物侧写;日志系统重构使用structlog;大量稳定性修复和性能优化。
|
||||||
|
|
||||||
|
|||||||
@@ -213,3 +213,4 @@ def analyze_expressions():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
analyze_expressions()
|
analyze_expressions()
|
||||||
|
|
||||||
|
|||||||
@@ -194,3 +194,4 @@ def analyze_group_similarity():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
analyze_group_similarity()
|
analyze_group_similarity()
|
||||||
|
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ class ExpressionSelector:
|
|||||||
expr["count"] = new_count
|
expr["count"] = new_count
|
||||||
expr["last_active_time"] = time.time()
|
expr["last_active_time"] = time.time()
|
||||||
|
|
||||||
# logger.info(f"表达方式激活: 原count={current_count:.2f}, 增量={increment}, 新count={new_count:.2f}")
|
logger.info(f"表达方式激活: 原count={current_count:.3f}, 增量={increment}, 新count={new_count:.3f}")
|
||||||
break
|
break
|
||||||
|
|
||||||
# 保存更新后的文件
|
# 保存更新后的文件
|
||||||
@@ -238,7 +238,7 @@ class ExpressionSelector:
|
|||||||
valid_expressions.append(expression)
|
valid_expressions.append(expression)
|
||||||
|
|
||||||
# 对选中的表达方式count数+0.1
|
# 对选中的表达方式count数+0.1
|
||||||
self.update_expression_count(chat_id, expression, 0.0001)
|
self.update_expression_count(chat_id, expression, 0.001)
|
||||||
|
|
||||||
# logger.info(f"LLM从{len(all_expressions)}个情境中选择了{len(valid_expressions)}个")
|
# logger.info(f"LLM从{len(all_expressions)}个情境中选择了{len(valid_expressions)}个")
|
||||||
return valid_expressions
|
return valid_expressions
|
||||||
|
|||||||
@@ -112,6 +112,13 @@ class HeartFChatting:
|
|||||||
|
|
||||||
self.memory_activator = MemoryActivator()
|
self.memory_activator = MemoryActivator()
|
||||||
|
|
||||||
|
# 新增:消息计数器和疲惫阈值
|
||||||
|
self._message_count = 0 # 发送的消息计数
|
||||||
|
# 基于exit_focus_threshold动态计算疲惫阈值
|
||||||
|
# 基础值30条,通过exit_focus_threshold调节:threshold越小,越容易疲惫
|
||||||
|
self._message_threshold = max(10, int(30 * global_config.chat.exit_focus_threshold))
|
||||||
|
self._fatigue_triggered = False # 是否已触发疲惫退出
|
||||||
|
|
||||||
# 初始化观察器
|
# 初始化观察器
|
||||||
self.observations: List[Observation] = []
|
self.observations: List[Observation] = []
|
||||||
self._register_observations()
|
self._register_observations()
|
||||||
@@ -177,6 +184,8 @@ class HeartFChatting:
|
|||||||
actual_version = performance_version or get_hfc_version()
|
actual_version = performance_version or get_hfc_version()
|
||||||
self.performance_logger = HFCPerformanceLogger(chat_id, actual_version)
|
self.performance_logger = HFCPerformanceLogger(chat_id, actual_version)
|
||||||
|
|
||||||
|
logger.info(f"{self.log_prefix} HeartFChatting 初始化完成,消息疲惫阈值: {self._message_threshold}条(基于exit_focus_threshold={global_config.chat.exit_focus_threshold}计算,仅在auto模式下生效)")
|
||||||
|
|
||||||
def _register_observations(self):
|
def _register_observations(self):
|
||||||
"""注册所有观察器"""
|
"""注册所有观察器"""
|
||||||
self.observations = [] # 清空已有的
|
self.observations = [] # 清空已有的
|
||||||
@@ -289,6 +298,9 @@ class HeartFChatting:
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# 重置消息计数器,开始新的focus会话
|
||||||
|
self.reset_message_count()
|
||||||
|
|
||||||
# 标记为活动状态,防止重复启动
|
# 标记为活动状态,防止重复启动
|
||||||
self._loop_active = True
|
self._loop_active = True
|
||||||
|
|
||||||
@@ -1164,6 +1176,24 @@ class HeartFChatting:
|
|||||||
command = action_data["_system_command"]
|
command = action_data["_system_command"]
|
||||||
logger.debug(f"{self.log_prefix} 从action_data中获取系统命令: {command}")
|
logger.debug(f"{self.log_prefix} 从action_data中获取系统命令: {command}")
|
||||||
|
|
||||||
|
# 新增:消息计数和疲惫检查
|
||||||
|
if action == "reply" and success:
|
||||||
|
self._message_count += 1
|
||||||
|
current_threshold = self._get_current_fatigue_threshold()
|
||||||
|
logger.info(f"{self.log_prefix} 已发送第 {self._message_count} 条消息(动态阈值: {current_threshold}, exit_focus_threshold: {global_config.chat.exit_focus_threshold})")
|
||||||
|
|
||||||
|
# 检查是否达到疲惫阈值(只有在auto模式下才会自动退出)
|
||||||
|
if (global_config.chat.chat_mode == "auto" and
|
||||||
|
self._message_count >= current_threshold and
|
||||||
|
not self._fatigue_triggered):
|
||||||
|
self._fatigue_triggered = True
|
||||||
|
logger.info(f"{self.log_prefix} [auto模式] 已发送 {self._message_count} 条消息,达到疲惫阈值 {current_threshold},麦麦感到疲惫了,准备退出专注聊天模式")
|
||||||
|
# 设置系统命令,在下次循环检查时触发退出
|
||||||
|
command = "stop_focus_chat"
|
||||||
|
elif (self._message_count >= current_threshold and
|
||||||
|
global_config.chat.chat_mode != "auto"):
|
||||||
|
logger.info(f"{self.log_prefix} [非auto模式] 已发送 {self._message_count} 条消息,达到疲惫阈值 {current_threshold},但非auto模式不会自动退出")
|
||||||
|
|
||||||
logger.debug(f"{self.log_prefix} 麦麦执行了'{action}', 返回结果'{success}', '{reply_text}', '{command}'")
|
logger.debug(f"{self.log_prefix} 麦麦执行了'{action}', 返回结果'{success}', '{reply_text}', '{command}'")
|
||||||
|
|
||||||
return success, reply_text, command
|
return success, reply_text, command
|
||||||
@@ -1173,11 +1203,45 @@ class HeartFChatting:
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return False, "", ""
|
return False, "", ""
|
||||||
|
|
||||||
|
def _get_current_fatigue_threshold(self) -> int:
|
||||||
|
"""动态获取当前的疲惫阈值,基于exit_focus_threshold配置
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: 当前的疲惫阈值
|
||||||
|
"""
|
||||||
|
return max(10, int(30 / global_config.chat.exit_focus_threshold))
|
||||||
|
|
||||||
|
def get_message_count_info(self) -> dict:
|
||||||
|
"""获取消息计数信息
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: 包含消息计数信息的字典
|
||||||
|
"""
|
||||||
|
current_threshold = self._get_current_fatigue_threshold()
|
||||||
|
return {
|
||||||
|
"current_count": self._message_count,
|
||||||
|
"threshold": current_threshold,
|
||||||
|
"fatigue_triggered": self._fatigue_triggered,
|
||||||
|
"remaining": max(0, current_threshold - self._message_count)
|
||||||
|
}
|
||||||
|
|
||||||
|
def reset_message_count(self):
|
||||||
|
"""重置消息计数器(用于重新启动focus模式时)"""
|
||||||
|
self._message_count = 0
|
||||||
|
self._fatigue_triggered = False
|
||||||
|
logger.info(f"{self.log_prefix} 消息计数器已重置")
|
||||||
|
|
||||||
async def shutdown(self):
|
async def shutdown(self):
|
||||||
"""优雅关闭HeartFChatting实例,取消活动循环任务"""
|
"""优雅关闭HeartFChatting实例,取消活动循环任务"""
|
||||||
logger.info(f"{self.log_prefix} 正在关闭HeartFChatting...")
|
logger.info(f"{self.log_prefix} 正在关闭HeartFChatting...")
|
||||||
self._shutting_down = True # <-- 在开始关闭时设置标志位
|
self._shutting_down = True # <-- 在开始关闭时设置标志位
|
||||||
|
|
||||||
|
# 记录最终的消息统计
|
||||||
|
if self._message_count > 0:
|
||||||
|
logger.info(f"{self.log_prefix} 本次focus会话共发送了 {self._message_count} 条消息")
|
||||||
|
if self._fatigue_triggered:
|
||||||
|
logger.info(f"{self.log_prefix} 因疲惫而退出focus模式")
|
||||||
|
|
||||||
# 取消循环任务
|
# 取消循环任务
|
||||||
if self._loop_task and not self._loop_task.done():
|
if self._loop_task and not self._loop_task.done():
|
||||||
logger.info(f"{self.log_prefix} 正在取消HeartFChatting循环任务")
|
logger.info(f"{self.log_prefix} 正在取消HeartFChatting循环任务")
|
||||||
@@ -1206,6 +1270,9 @@ class HeartFChatting:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"{self.log_prefix} 完成性能统计时出错: {e}")
|
logger.warning(f"{self.log_prefix} 完成性能统计时出错: {e}")
|
||||||
|
|
||||||
|
# 重置消息计数器,为下次启动做准备
|
||||||
|
self.reset_message_count()
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} HeartFChatting关闭完成")
|
logger.info(f"{self.log_prefix} HeartFChatting关闭完成")
|
||||||
|
|
||||||
def get_cycle_history(self, last_n: Optional[int] = None) -> List[Dict[str, Any]]:
|
def get_cycle_history(self, last_n: Optional[int] = None) -> List[Dict[str, Any]]:
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ class NoReplyAction(BaseAction):
|
|||||||
# 使用 utils_small 模型
|
# 使用 utils_small 模型
|
||||||
small_model = getattr(available_models, "utils_small", None)
|
small_model = getattr(available_models, "utils_small", None)
|
||||||
|
|
||||||
print(judge_prompt)
|
logger.debug(judge_prompt)
|
||||||
|
|
||||||
if small_model:
|
if small_model:
|
||||||
# 使用小模型进行判断
|
# 使用小模型进行判断
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ class EmojiAction(BaseAction):
|
|||||||
normal_activation_type = ActionActivationType.RANDOM
|
normal_activation_type = ActionActivationType.RANDOM
|
||||||
mode_enable = ChatMode.ALL
|
mode_enable = ChatMode.ALL
|
||||||
parallel_action = True
|
parallel_action = True
|
||||||
random_activation_probability = 0.1 # 默认值,可通过配置覆盖
|
random_activation_probability = 0.2 # 默认值,可通过配置覆盖
|
||||||
|
|
||||||
# 动作基本信息
|
# 动作基本信息
|
||||||
action_name = "emoji"
|
action_name = "emoji"
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ class MuteAction(BaseAction):
|
|||||||
if allowed_group == current_group_key:
|
if allowed_group == current_group_key:
|
||||||
logger.info(f"{self.log_prefix} 群组 {current_group_key} 有禁言动作权限")
|
logger.info(f"{self.log_prefix} 群组 {current_group_key} 有禁言动作权限")
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
logger.warning(f"{self.log_prefix} 群组 {current_group_key} 没有禁言动作权限")
|
logger.warning(f"{self.log_prefix} 群组 {current_group_key} 没有禁言动作权限")
|
||||||
return False, "当前群组没有使用禁言动作的权限"
|
return False, "当前群组没有使用禁言动作的权限"
|
||||||
|
|
||||||
@@ -125,10 +125,6 @@ class MuteAction(BaseAction):
|
|||||||
|
|
||||||
# 首先检查群组权限
|
# 首先检查群组权限
|
||||||
has_permission, permission_error = self._check_group_permission()
|
has_permission, permission_error = self._check_group_permission()
|
||||||
if not has_permission:
|
|
||||||
logger.error(f"{self.log_prefix} 权限检查失败: {permission_error}")
|
|
||||||
# 不发送错误消息,静默拒绝
|
|
||||||
return False, permission_error
|
|
||||||
|
|
||||||
# 获取参数
|
# 获取参数
|
||||||
target = self.action_data.get("target")
|
target = self.action_data.get("target")
|
||||||
@@ -190,6 +186,32 @@ class MuteAction(BaseAction):
|
|||||||
|
|
||||||
# 获取模板化消息
|
# 获取模板化消息
|
||||||
message = self._get_template_message(target, time_str, reason)
|
message = self._get_template_message(target, time_str, reason)
|
||||||
|
|
||||||
|
if not has_permission:
|
||||||
|
logger.warning(f"{self.log_prefix} 权限检查失败: {permission_error}")
|
||||||
|
result_status, result_message = await generator_api.rewrite_reply(
|
||||||
|
chat_stream=self.chat_stream,
|
||||||
|
reply_data={
|
||||||
|
"raw_reply": "我想禁言{target},但是我没有权限",
|
||||||
|
"reason": "表达自己没有在这个群禁言的能力",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if result_status:
|
||||||
|
for reply_seg in result_message:
|
||||||
|
data = reply_seg[1]
|
||||||
|
await self.send_text(data)
|
||||||
|
|
||||||
|
await self.store_action_info(
|
||||||
|
action_build_into_prompt=True,
|
||||||
|
action_prompt_display=f"尝试禁言了用户 {target},但是没有权限,无法禁言",
|
||||||
|
action_done=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 不发送错误消息,静默拒绝
|
||||||
|
return False, permission_error
|
||||||
|
|
||||||
result_status, result_message = await generator_api.rewrite_reply(
|
result_status, result_message = await generator_api.rewrite_reply(
|
||||||
chat_stream=self.chat_stream,
|
chat_stream=self.chat_stream,
|
||||||
|
|||||||
Reference in New Issue
Block a user