feat(chat): 实现批量动作存储并优化消息处理流程

新增批量动作记录存储功能,提升数据库写入性能。重构消息预处理逻辑,改进兴趣度计算和同步机制,优化用户信息和群组信息处理。添加配置选项控制批量存储开关,更新相关模板配置。
This commit is contained in:
Windpicker-owo
2025-10-05 17:45:44 +08:00
parent 23e523c7b9
commit c808d6a0ef
8 changed files with 307 additions and 93 deletions

View File

@@ -1,5 +1,6 @@
import os
import re
import time
import traceback
from typing import Any
@@ -468,55 +469,110 @@ class ChatBot:
template_group_name = None
async def preprocess():
# 存储消息到数据库
from .storage import MessageStorage
try:
await MessageStorage.store_message(message, message.chat_stream)
logger.debug(f"消息已存储到数据库: {message.message_info.message_id}")
except Exception as e:
logger.error(f"存储消息到数据库失败: {e}")
traceback.print_exc()
# 使用消息管理器处理消息(保持原有功能)
from src.common.data_models.database_data_model import DatabaseMessages
message_info = message.message_info
msg_user_info = getattr(message_info, "user_info", None)
stream_user_info = getattr(message.chat_stream, "user_info", None)
group_info = getattr(message.chat_stream, "group_info", None)
message_id = message_info.message_id or ""
message_time = message_info.time if message_info.time is not None else time.time()
is_mentioned = None
if isinstance(message.is_mentioned, bool):
is_mentioned = message.is_mentioned
elif isinstance(message.is_mentioned, (int, float)):
is_mentioned = message.is_mentioned != 0
user_id = ""
user_nickname = ""
user_cardname = None
user_platform = ""
if msg_user_info:
user_id = str(getattr(msg_user_info, "user_id", "") or "")
user_nickname = getattr(msg_user_info, "user_nickname", "") or ""
user_cardname = getattr(msg_user_info, "user_cardname", None)
user_platform = getattr(msg_user_info, "platform", "") or ""
elif stream_user_info:
user_id = str(getattr(stream_user_info, "user_id", "") or "")
user_nickname = getattr(stream_user_info, "user_nickname", "") or ""
user_cardname = getattr(stream_user_info, "user_cardname", None)
user_platform = getattr(stream_user_info, "platform", "") or ""
chat_user_id = str(getattr(stream_user_info, "user_id", "") or "")
chat_user_nickname = getattr(stream_user_info, "user_nickname", "") or ""
chat_user_cardname = getattr(stream_user_info, "user_cardname", None)
chat_user_platform = getattr(stream_user_info, "platform", "") or ""
group_id = getattr(group_info, "group_id", None)
group_name = getattr(group_info, "group_name", None)
group_platform = getattr(group_info, "platform", None)
# 创建数据库消息对象
db_message = DatabaseMessages(
message_id=message.message_info.message_id,
time=message.message_info.time,
message_id=message_id,
time=float(message_time),
chat_id=message.chat_stream.stream_id,
processed_plain_text=message.processed_plain_text,
display_message=message.processed_plain_text,
is_mentioned=message.is_mentioned,
is_at=message.is_at,
is_emoji=message.is_emoji,
is_picid=message.is_picid,
is_command=message.is_command,
is_notify=message.is_notify,
user_id=message.message_info.user_info.user_id,
user_nickname=message.message_info.user_info.user_nickname,
user_cardname=message.message_info.user_info.user_cardname,
user_platform=message.message_info.user_info.platform,
is_mentioned=is_mentioned,
is_at=bool(message.is_at) if message.is_at is not None else None,
is_emoji=bool(message.is_emoji),
is_picid=bool(message.is_picid),
is_command=bool(message.is_command),
is_notify=bool(message.is_notify),
user_id=user_id,
user_nickname=user_nickname,
user_cardname=user_cardname,
user_platform=user_platform,
chat_info_stream_id=message.chat_stream.stream_id,
chat_info_platform=message.chat_stream.platform,
chat_info_create_time=message.chat_stream.create_time,
chat_info_last_active_time=message.chat_stream.last_active_time,
chat_info_user_id=message.chat_stream.user_info.user_id,
chat_info_user_nickname=message.chat_stream.user_info.user_nickname,
chat_info_user_cardname=message.chat_stream.user_info.user_cardname,
chat_info_user_platform=message.chat_stream.user_info.platform,
chat_info_create_time=float(message.chat_stream.create_time),
chat_info_last_active_time=float(message.chat_stream.last_active_time),
chat_info_user_id=chat_user_id,
chat_info_user_nickname=chat_user_nickname,
chat_info_user_cardname=chat_user_cardname,
chat_info_user_platform=chat_user_platform,
chat_info_group_id=group_id,
chat_info_group_name=group_name,
chat_info_group_platform=group_platform,
)
# 如果是群聊,添加群组信息
if message.chat_stream.group_info:
db_message.chat_info_group_id = message.chat_stream.group_info.group_id
db_message.chat_info_group_name = message.chat_stream.group_info.group_name
db_message.chat_info_group_platform = message.chat_stream.group_info.platform
# 兼容历史逻辑:显式设置群聊相关属性,便于后续逻辑通过 hasattr 判断
if group_info:
setattr(db_message, "chat_info_group_id", group_id)
setattr(db_message, "chat_info_group_name", group_name)
setattr(db_message, "chat_info_group_platform", group_platform)
else:
setattr(db_message, "chat_info_group_id", None)
setattr(db_message, "chat_info_group_name", None)
setattr(db_message, "chat_info_group_platform", None)
# 添加消息到消息管理器
await message_manager.add_message(message.chat_stream.stream_id, db_message)
logger.debug(f"消息已添加到消息管理器: {message.chat_stream.stream_id}")
# 先交给消息管理器处理,计算兴趣度等衍生数据
try:
await message_manager.add_message(message.chat_stream.stream_id, db_message)
logger.debug(f"消息已添加到消息管理器: {message.chat_stream.stream_id}")
except Exception as e:
logger.error(f"消息添加到消息管理器失败: {e}")
# 将兴趣度结果同步回原始消息,便于后续流程使用
message.interest_value = getattr(db_message, "interest_value", getattr(message, "interest_value", 0.0))
setattr(message, "should_reply", getattr(db_message, "should_reply", getattr(message, "should_reply", False)))
setattr(message, "should_act", getattr(db_message, "should_act", getattr(message, "should_act", False)))
# 存储消息到数据库,只进行一次写入
try:
await MessageStorage.store_message(message, message.chat_stream)
logger.debug(
"消息已存储到数据库: %s (interest=%.3f, should_reply=%s, should_act=%s)",
message.message_info.message_id,
getattr(message, "interest_value", -1.0),
getattr(message, "should_reply", None),
getattr(message, "should_act", None),
)
except Exception as e:
logger.error(f"存储消息到数据库失败: {e}")
traceback.print_exc()
if template_group_name:
async with global_prompt_manager.async_message_scope(template_group_name):

View File

@@ -33,6 +33,10 @@ class ChatterActionManager:
self._using_actions = component_registry.get_default_actions()
self.log_prefix: str = "ChatterActionManager"
# 批量存储支持
self._batch_storage_enabled = False
self._pending_actions = []
self._current_chat_id = None
# === 执行Action方法 ===
@@ -184,16 +188,26 @@ class ChatterActionManager:
reason = reasoning or "选择不回复"
logger.info(f"{log_prefix} 选择不回复,原因: {reason}")
# 存储no_reply信息到数据库
asyncio.create_task(database_api.store_action_info(
chat_stream=chat_stream,
action_build_into_prompt=False,
action_prompt_display=reason,
action_done=True,
thinking_id=thinking_id,
action_data={"reason": reason},
action_name="no_reply",
))
# 存储no_reply信息到数据库(支持批量存储)
if self._batch_storage_enabled:
self.add_action_to_batch(
action_name="no_reply",
action_data={"reason": reason},
thinking_id=thinking_id or "",
action_done=True,
action_build_into_prompt=False,
action_prompt_display=reason
)
else:
asyncio.create_task(database_api.store_action_info(
chat_stream=chat_stream,
action_build_into_prompt=False,
action_prompt_display=reason,
action_done=True,
thinking_id=thinking_id,
action_data={"reason": reason},
action_name="no_reply",
))
# 自动清空所有未读消息
asyncio.create_task(self._clear_all_unread_messages(chat_stream.stream_id, "no_reply"))
@@ -474,16 +488,26 @@ class ChatterActionManager:
person_name = await person_info_manager.get_value(person_id, "person_name")
action_prompt_display = f"你对{person_name}进行了回复:{reply_text}"
# 存储动作信息到数据库
await database_api.store_action_info(
chat_stream=chat_stream,
action_build_into_prompt=False,
action_prompt_display=action_prompt_display,
action_done=True,
thinking_id=thinking_id,
action_data={"reply_text": reply_text},
action_name="reply",
)
# 存储动作信息到数据库(支持批量存储)
if self._batch_storage_enabled:
self.add_action_to_batch(
action_name="reply",
action_data={"reply_text": reply_text},
thinking_id=thinking_id or "",
action_done=True,
action_build_into_prompt=False,
action_prompt_display=action_prompt_display
)
else:
await database_api.store_action_info(
chat_stream=chat_stream,
action_build_into_prompt=False,
action_prompt_display=action_prompt_display,
action_done=True,
thinking_id=thinking_id,
action_data={"reply_text": reply_text},
action_name="reply",
)
# 构建循环信息
loop_info: dict[str, Any] = {
@@ -579,3 +603,71 @@ class ChatterActionManager:
)
return reply_text
def enable_batch_storage(self, chat_id: str):
"""启用批量存储模式"""
self._batch_storage_enabled = True
self._current_chat_id = chat_id
self._pending_actions.clear()
logger.debug(f"已启用批量存储模式chat_id: {chat_id}")
def disable_batch_storage(self):
"""禁用批量存储模式"""
self._batch_storage_enabled = False
self._current_chat_id = None
logger.debug("已禁用批量存储模式")
def add_action_to_batch(self, action_name: str, action_data: dict, thinking_id: str = "",
action_done: bool = True, action_build_into_prompt: bool = False,
action_prompt_display: str = ""):
"""添加动作到批量存储列表"""
if not self._batch_storage_enabled:
return False
action_record = {
"action_name": action_name,
"action_data": action_data,
"thinking_id": thinking_id,
"action_done": action_done,
"action_build_into_prompt": action_build_into_prompt,
"action_prompt_display": action_prompt_display,
"timestamp": time.time()
}
self._pending_actions.append(action_record)
logger.debug(f"已添加动作到批量存储列表: {action_name} (当前待处理: {len(self._pending_actions)} 个)")
return True
async def flush_batch_storage(self, chat_stream):
"""批量存储所有待处理的动作记录"""
if not self._pending_actions:
logger.debug("没有待处理的动作需要批量存储")
return
try:
logger.info(f"开始批量存储 {len(self._pending_actions)} 个动作记录")
# 批量存储所有动作
stored_count = 0
for action_data in self._pending_actions:
try:
result = await database_api.store_action_info(
chat_stream=chat_stream,
action_name=action_data.get("action_name", ""),
action_data=action_data.get("action_data", {}),
action_done=action_data.get("action_done", True),
action_build_into_prompt=action_data.get("action_build_into_prompt", False),
action_prompt_display=action_data.get("action_prompt_display", ""),
thinking_id=action_data.get("thinking_id", "")
)
if result:
stored_count += 1
except Exception as e:
logger.error(f"存储单个动作记录失败: {e}")
logger.info(f"批量存储完成: 成功存储 {stored_count}/{len(self._pending_actions)} 个动作记录")
# 清空待处理列表
self._pending_actions.clear()
except Exception as e:
logger.error(f"批量存储动作记录时发生错误: {e}")

View File

@@ -36,6 +36,9 @@ class DatabaseConfig(ValidatedConfigBase):
connection_pool_size: int = Field(default=10, ge=1, description="连接池大小")
connection_timeout: int = Field(default=10, ge=1, description="连接超时时间")
# 批量动作记录存储配置
batch_action_storage_enabled: bool = Field(default=True, description="是否启用批量保存动作记录(开启后将多个动作一次性写入数据库,提升性能)")
class BotConfig(ValidatedConfigBase):
"""QQ机器人配置类"""
@@ -685,6 +688,7 @@ class AffinityFlowConfig(ValidatedConfigBase):
base_relationship_score: float = Field(default=0.5, description="基础人物关系分")
class ProactiveThinkingConfig(ValidatedConfigBase):
"""主动思考(主动发起对话)功能配置"""

View File

@@ -32,7 +32,7 @@ class InterestCalculationResult:
):
self.success = success
self.message_id = message_id
self.interest_value = max(0.0, min(1.0, interest_value)) # 确保在0-1范围内
self.interest_value = interest_value
self.should_take_action = should_take_action
self.should_reply = should_reply
self.should_act = should_act

View File

@@ -4,6 +4,7 @@
"""
import time
import orjson
from typing import TYPE_CHECKING
from src.chat.interest_system import bot_interest_manager
@@ -42,6 +43,9 @@ class AffinityInterestCalculator(BaseInterestCalculator):
self.reply_threshold = affinity_config.reply_action_interest_threshold # 回复动作兴趣阈值
self.mention_threshold = affinity_config.mention_bot_adjustment_threshold # 提及bot后的调整阈值
# 兴趣匹配系统配置
self.use_smart_matching = True
# 连续不回复概率提升
self.no_reply_count = 0
self.max_no_reply_count = affinity_config.max_no_reply_count
@@ -71,7 +75,11 @@ class AffinityInterestCalculator(BaseInterestCalculator):
start_time = time.time()
message_id = getattr(message, "message_id", "")
content = getattr(message, "processed_plain_text", "")
user_id = getattr(message, "user_info", {}).user_id if hasattr(message, "user_info") and hasattr(message.user_info, "user_id") else ""
user_info = getattr(message, "user_info", None)
if user_info and hasattr(user_info, "user_id"):
user_id = user_info.user_id
else:
user_id = ""
logger.debug(f"[Affinity兴趣计算] 开始处理消息 {message_id}")
logger.debug(f"[Affinity兴趣计算] 消息内容: {content[:50]}...")
@@ -111,10 +119,18 @@ class AffinityInterestCalculator(BaseInterestCalculator):
logger.debug(f"[Affinity兴趣计算] 应用不回复提升后: {total_score:.3f}{adjusted_score:.3f}")
# 6. 决定是否回复和执行动作
should_reply = adjusted_score > self.reply_threshold
should_take_action = adjusted_score > (self.reply_threshold + 0.1)
logger.debug(f"[Affinity兴趣计算] 阈值判断: {adjusted_score:.3f} > 回复阈值:{self.reply_threshold:.3f}? = {should_reply}")
logger.debug(f"[Affinity兴趣计算] 阈值判断: {adjusted_score:.3f} > 动作阈值:{self.reply_threshold + 0.1:.3f}? = {should_take_action}")
reply_threshold = self.reply_threshold
action_threshold = global_config.affinity_flow.non_reply_action_interest_threshold
should_reply = adjusted_score >= reply_threshold
should_take_action = adjusted_score >= action_threshold
logger.debug(
f"[Affinity兴趣计算] 阈值判断: {adjusted_score:.3f} >= 回复阈值:{reply_threshold:.3f}? = {should_reply}"
)
logger.debug(
f"[Affinity兴趣计算] 阈值判断: {adjusted_score:.3f} >= 动作阈值:{action_threshold:.3f}? = {should_take_action}"
)
calculation_time = time.time() - start_time
@@ -140,7 +156,7 @@ class AffinityInterestCalculator(BaseInterestCalculator):
error_message=str(e)
)
async def _calculate_interest_match_score(self, content: str, keywords: list[str] = None) -> float:
async def _calculate_interest_match_score(self, content: str, keywords: list[str] | None = None) -> float:
"""计算兴趣匹配度(使用智能兴趣匹配系统)"""
# 调试日志:检查各个条件
@@ -158,7 +174,7 @@ class AffinityInterestCalculator(BaseInterestCalculator):
try:
# 使用机器人的兴趣标签系统进行智能匹配
match_result = await bot_interest_manager.calculate_interest_match(content, keywords)
match_result = await bot_interest_manager.calculate_interest_match(content, keywords or [])
logger.debug(f"兴趣匹配结果: {match_result}")
if match_result:
@@ -241,7 +257,6 @@ class AffinityInterestCalculator(BaseInterestCalculator):
key_words = getattr(message, "key_words", "")
if key_words:
try:
import orjson
extracted = orjson.loads(key_words)
if isinstance(extracted, list):
keywords = extracted
@@ -253,7 +268,6 @@ class AffinityInterestCalculator(BaseInterestCalculator):
key_words_lite = getattr(message, "key_words_lite", "")
if key_words_lite:
try:
import orjson
extracted = orjson.loads(key_words_lite)
if isinstance(extracted, list):
keywords = extracted
@@ -296,6 +310,3 @@ class AffinityInterestCalculator(BaseInterestCalculator):
self.no_reply_count = 0
else:
self.no_reply_count = min(self.no_reply_count + 1, self.max_no_reply_count)
# 是否使用智能兴趣匹配(作为类属性)
use_smart_matching = True

View File

@@ -69,6 +69,13 @@ class ChatterPlanExecutor:
action_types = [action.action_type for action in plan.decided_actions]
logger.info(f"选择动作: {', '.join(action_types) if action_types else ''}")
# 根据配置决定是否启用批量存储模式
if global_config.database.batch_action_storage_enabled:
self.action_manager.enable_batch_storage(plan.chat_id)
logger.debug("已启用批量存储模式")
else:
logger.debug("批量存储功能已禁用,使用立即存储模式")
execution_results = []
reply_actions = []
other_actions = []
@@ -102,6 +109,9 @@ class ChatterPlanExecutor:
f"规划执行完成: 总数={len(plan.decided_actions)}, 成功={successful_count}, 失败={len(execution_results) - successful_count}"
)
# 批量存储所有待处理的动作
await self._flush_action_manager_batch_storage(plan)
return {
"executed_count": len(plan.decided_actions),
"successful_count": successful_count,
@@ -395,6 +405,7 @@ class ChatterPlanExecutor:
# 移除执行时间列表以避免返回过大数据
stats.pop("execution_times", None)
return stats
def reset_stats(self):
@@ -422,3 +433,26 @@ class ChatterPlanExecutor:
}
for i, time_val in enumerate(recent_times)
]
async def _flush_action_manager_batch_storage(self, plan: Plan):
"""使用 action_manager 的批量存储功能存储所有待处理的动作"""
try:
# 通过 chat_id 获取真实的 chat_stream 对象
from src.plugin_system.apis.chat_api import get_chat_manager
chat_manager = get_chat_manager()
chat_stream = chat_manager.get_stream(plan.chat_id)
if chat_stream:
# 调用 action_manager 的批量存储
await self.action_manager.flush_batch_storage(chat_stream)
logger.info("批量存储完成:通过 action_manager 存储所有动作记录")
# 禁用批量存储模式
self.action_manager.disable_batch_storage()
except Exception as e:
logger.error(f"批量存储动作记录时发生错误: {e}")
# 确保在出错时也禁用批量存储模式
self.action_manager.disable_batch_storage()

View File

@@ -13,6 +13,7 @@ from src.mood.mood_manager import mood_manager
from src.plugins.built_in.affinity_flow_chatter.plan_executor import ChatterPlanExecutor
from src.plugins.built_in.affinity_flow_chatter.plan_filter import ChatterPlanFilter
from src.plugins.built_in.affinity_flow_chatter.plan_generator import ChatterPlanGenerator
from src.plugin_system.base.component_types import ChatMode
if TYPE_CHECKING:
from src.chat.planner_actions.action_manager import ChatterActionManager
@@ -60,7 +61,7 @@ class ChatterActionPlanner:
"other_actions_executed": 0,
}
async def plan(self, context: "StreamContext" = None) -> tuple[list[dict], dict | None]:
async def plan(self, context: "StreamContext | None" = None) -> tuple[list[dict[str, Any]], Any | None]:
"""
执行完整的增强版规划流程。
@@ -82,7 +83,7 @@ class ChatterActionPlanner:
self.planner_stats["failed_plans"] += 1
return [], None
async def _enhanced_plan_flow(self, context: "StreamContext") -> tuple[list[dict], dict | None]:
async def _enhanced_plan_flow(self, context: "StreamContext | None") -> tuple[list[dict[str, Any]], Any | None]:
"""执行增强版规划流程"""
try:
# 在规划前,先进行动作修改
@@ -92,39 +93,48 @@ class ChatterActionPlanner:
await action_modifier.modify_actions()
# 1. 生成初始 Plan
initial_plan = await self.generator.generate(context.chat_mode)
chat_mode = context.chat_mode if context else ChatMode.NORMAL
initial_plan = await self.generator.generate(chat_mode)
# 确保Plan中包含所有当前可用的动作
initial_plan.available_actions = self.action_manager.get_using_actions()
unread_messages = context.get_unread_messages() if context else []
# 2. 使用新的兴趣度管理系统进行评分
message_interest = 0.0
reply_not_available = False
max_message_interest = 0.0
reply_not_available = True
interest_updates: list[dict[str, Any]] = []
message_should_act = False
message_should_reply = False
aggregate_should_act = False
aggregate_should_reply = False
if unread_messages:
# 直接使用消息中已计算的标志,无需重复计算兴趣值
for message in unread_messages:
try:
message_interest = getattr(message, "interest_value", 0.3)
raw_interest = getattr(message, "interest_value", 0.3)
if raw_interest is None:
raw_interest = 0.0
message_interest = float(raw_interest)
max_message_interest = max(max_message_interest, message_interest)
message_should_reply = getattr(message, "should_reply", False)
message_should_act = getattr(message, "should_act", False)
if not message_should_reply:
reply_not_available = True
# 如果should_act为false强制设为no_action
if not message_should_act:
reply_not_available = True
logger.debug(
f"消息 {message.message_id} 预计算标志: interest={message_interest:.3f}, "
f"should_reply={message_should_reply}, should_act={message_should_act}"
)
if message_should_reply:
aggregate_should_reply = True
aggregate_should_act = True
reply_not_available = False
break
if message_should_act:
aggregate_should_act = True
except Exception as e:
logger.warning(f"处理消息 {message.message_id} 失败: {e}")
message.interest_value = 0.0
@@ -144,14 +154,18 @@ class ChatterActionPlanner:
# 检查兴趣度是否达到非回复动作阈值
non_reply_action_interest_threshold = global_config.affinity_flow.non_reply_action_interest_threshold
if not message_should_act:
logger.info(f"兴趣度 {message_interest:.3f} 低于阈值 {non_reply_action_interest_threshold:.3f},不执行动作")
if not aggregate_should_act:
logger.info("所有未读消息低于兴趣度阈值,不执行动作")
# 直接返回 no_action
from src.common.data_models.info_data_model import ActionPlannerInfo
no_action = ActionPlannerInfo(
action_type="no_action",
reasoning=f"兴趣度评分 {message_interest:.3f} 未达阈值 {non_reply_action_interest_threshold:.3f}",
reasoning=(
"所有未读消息兴趣度未达阈值 "
f"{non_reply_action_interest_threshold:.3f}"
f"(最高兴趣度 {max_message_interest:.3f}"
),
action_data={},
action_message=None,
)
@@ -204,7 +218,7 @@ class ChatterActionPlanner:
except Exception as e:
logger.warning(f"批量更新数据库兴趣度失败: {e}")
def _update_stats_from_execution_result(self, execution_result: dict[str, any]):
def _update_stats_from_execution_result(self, execution_result: dict[str, Any]):
"""根据执行结果更新规划器统计"""
if not execution_result:
return
@@ -228,7 +242,7 @@ class ChatterActionPlanner:
self.planner_stats["replies_generated"] += reply_count
self.planner_stats["other_actions_executed"] += other_count
def _build_return_result(self, plan: "Plan") -> tuple[list[dict], dict | None]:
def _build_return_result(self, plan: "Plan") -> tuple[list[dict[str, Any]], Any | None]:
"""构建返回结果"""
final_actions = plan.decided_actions or []
final_target_message = next((act.action_message for act in final_actions if act.action_message), None)
@@ -245,7 +259,7 @@ class ChatterActionPlanner:
return final_actions_dict, final_target_message_dict
def get_planner_stats(self) -> dict[str, any]:
def get_planner_stats(self) -> dict[str, Any]:
"""获取规划器统计"""
return self.planner_stats.copy()
@@ -254,7 +268,7 @@ class ChatterActionPlanner:
chat_mood = mood_manager.get_mood_by_chat_id(self.chat_id)
return chat_mood.mood_state
def get_mood_stats(self) -> dict[str, any]:
def get_mood_stats(self) -> dict[str, Any]:
"""获取情绪状态统计"""
chat_mood = mood_manager.get_mood_by_chat_id(self.chat_id)
return {

View File

@@ -1,5 +1,5 @@
[inner]
version = "7.1.8"
version = "7.2.1"
#----以下是给开发人员阅读的如果你只是部署了MoFox-Bot不需要阅读----
#如果你想要修改配置文件请递增version的值
@@ -40,6 +40,9 @@ mysql_sql_mode = "TRADITIONAL" # SQL模式
connection_pool_size = 10 # 连接池大小仅MySQL有效
connection_timeout = 10 # 连接超时时间(秒)
# 批量动作记录存储配置
batch_action_storage_enabled = true # 是否启用批量保存动作记录(开启后将多个动作一次性写入数据库,提升性能)
[permission] # 权限系统配置
# Master用户配置拥有最高权限无视所有权限节点
# 格式:[[platform, user_id], ...]