+
+ 统计时段:
+ {start_time.strftime("%Y-%m-%d %H:%M:%S")} ~ {now.strftime("%Y-%m-%d %H:%M:%S")}
+
+
总在线时间: {_format_online_time(stat_data[ONLINE_TIME])}
+
总消息数: {stat_data[TOTAL_MSG_CNT]}
+
总请求数: {stat_data[TOTAL_REQ_CNT]}
+
总花费: {stat_data[TOTAL_COST]:.4f} ¥
+
+
按模型分类统计
+
+ | 模型名称 | 调用次数 | 输入Token | 输出Token | Token总量 | 累计花费 |
+
+ {model_rows}
+
+
+
+
按请求类型分类统计
+
+
+ | 请求类型 | 调用次数 | 输入Token | 输出Token | Token总量 | 累计花费 |
+
+
+ {type_rows}
+
+
+
+
按用户分类统计
+
+
+ | 用户名称 | 调用次数 | 输入Token | 输出Token | Token总量 | 累计花费 |
+
+
+ {user_rows}
+
+
+
+
聊天消息统计
+
+
+ | 联系人/群组名称 | 消息数量 |
+
+
+ {chat_rows}
+
+
+
+ """
+
+ tab_content_list = [
+ _format_stat_data(stat[period[0]], period[0], now - period[1])
+ for period in self.stat_period
+ if period[0] != "all_time"
+ ]
+
+ tab_content_list.append(
+ _format_stat_data(stat["all_time"], "all_time", datetime.fromtimestamp(local_storage["deploy_time"]))
+ )
+
+ joined_tab_list = "\n".join(tab_list)
+ joined_tab_content = "\n".join(tab_content_list)
+
+ html_template = (
+ """
+
+
+
+
-
- 统计时段:
- {start_time_dt_for_period.strftime("%Y-%m-%d %H:%M:%S")} ~ {now.strftime("%Y-%m-%d %H:%M:%S")}
-
-
总在线时间: {_format_online_time(current_period_stats.get(ONLINE_TIME, 0))}
-
总消息数: {current_period_stats.get(TOTAL_MSG_CNT, 0)}
-
总请求数: {current_period_stats.get(TOTAL_REQ_CNT, 0)}
-
总花费: {current_period_stats.get(TOTAL_COST, 0.0):.4f} ¥
- """
-
- html_content_for_tab += "
按模型分类统计
| 模型名称 | 调用次数 | 输入Token | 输出Token | Token总量 | 累计花费 |
"
- req_cnt_by_model = current_period_stats.get(REQ_CNT_BY_MODEL, {})
- in_tok_by_model = current_period_stats.get(IN_TOK_BY_MODEL, defaultdict(int))
- out_tok_by_model = current_period_stats.get(OUT_TOK_BY_MODEL, defaultdict(int))
- total_tok_by_model = current_period_stats.get(TOTAL_TOK_BY_MODEL, defaultdict(int))
- cost_by_model = current_period_stats.get(COST_BY_MODEL, defaultdict(float))
- if req_cnt_by_model:
- for model_name, count in sorted(req_cnt_by_model.items()):
- html_content_for_tab += (
- f""
- f"| {model_name} | "
- f"{count} | "
- f"{in_tok_by_model[model_name]} | "
- f"{out_tok_by_model[model_name]} | "
- f"{total_tok_by_model[model_name]} | "
- f"{cost_by_model[model_name]:.4f} ¥ | "
- f"
"
- )
- else:
- html_content_for_tab += "| 无数据 |
"
- html_content_for_tab += "
"
-
- html_content_for_tab += "
按请求类型分类统计
| 请求类型 | 调用次数 | 输入Token | 输出Token | Token总量 | 累计花费 |
"
- req_cnt_by_type = current_period_stats.get(REQ_CNT_BY_TYPE, {})
- in_tok_by_type = current_period_stats.get(IN_TOK_BY_TYPE, defaultdict(int))
- out_tok_by_type = current_period_stats.get(OUT_TOK_BY_TYPE, defaultdict(int))
- total_tok_by_type = current_period_stats.get(TOTAL_TOK_BY_TYPE, defaultdict(int))
- cost_by_type = current_period_stats.get(COST_BY_TYPE, defaultdict(float))
- if req_cnt_by_type:
- for req_type, count in sorted(req_cnt_by_type.items()):
- html_content_for_tab += (
- f""
- f"| {req_type} | "
- f"{count} | "
- f"{in_tok_by_type[req_type]} | "
- f"{out_tok_by_type[req_type]} | "
- f"{total_tok_by_type[req_type]} | "
- f"{cost_by_type[req_type]:.4f} ¥ | "
- f"
"
- )
- else:
- html_content_for_tab += "| 无数据 |
"
- html_content_for_tab += "
"
-
- html_content_for_tab += "
按用户分类统计
| 用户ID/名称 | 调用次数 | 输入Token | 输出Token | Token总量 | 累计花费 |
"
- req_cnt_by_user = current_period_stats.get(REQ_CNT_BY_USER, {})
- in_tok_by_user = current_period_stats.get(IN_TOK_BY_USER, defaultdict(int))
- out_tok_by_user = current_period_stats.get(OUT_TOK_BY_USER, defaultdict(int))
- total_tok_by_user = current_period_stats.get(TOTAL_TOK_BY_USER, defaultdict(int))
- cost_by_user = current_period_stats.get(COST_BY_USER, defaultdict(float))
- if req_cnt_by_user:
- for user_id, count in sorted(req_cnt_by_user.items()):
- user_display_name = self.name_mapping.get(user_id, (user_id, None))[0]
- html_content_for_tab += (
- f""
- f"| {user_display_name} | "
- f"{count} | "
- f"{in_tok_by_user[user_id]} | "
- f"{out_tok_by_user[user_id]} | "
- f"{total_tok_by_user[user_id]} | "
- f"{cost_by_user[user_id]:.4f} ¥ | "
- f"
"
- )
- else:
- html_content_for_tab += "| 无数据 |
"
- html_content_for_tab += "
"
-
- html_content_for_tab += "
聊天消息统计
| 联系人/群组名称 | 消息数量 |
"
- msg_cnt_by_chat = current_period_stats.get(MSG_CNT_BY_CHAT, {})
- if msg_cnt_by_chat:
- for chat_id, count in sorted(msg_cnt_by_chat.items()):
- chat_name_display = self.name_mapping.get(chat_id, (f"未知/归档聊天 ({chat_id})", None))[0]
- html_content_for_tab += f"| {chat_name_display} | {count} |
"
- else:
- html_content_for_tab += "| 无数据 |
"
- html_content_for_tab += "
"
-
- tab_content_html_list.append(html_content_for_tab)
-
-
- html_template = (
- """
-
-
-
-
-
MaiBot运行统计报告
-
统计截止时间: {now.strftime("%Y-%m-%d %H:%M:%S")}
-
-
- {"".join(tab_list_html)}
-
-
- {"".join(tab_content_html_list)}
-
-
-
-"""
- + """
-
-
-
- """
- )
-
- try:
- with open(self.record_file_path, "w", encoding="utf-8") as f:
- f.write(html_template)
- logger.info(f"统计报告已生成: {self.record_file_path}")
- except IOError as e:
- logger.error(f"无法写入统计报告文件 {self.record_file_path}: {e}")
-
diff --git a/src/plugins/willing/mode_dynamic.py b/src/plugins/willing/mode_dynamic.py
deleted file mode 100644
index 029da4e0..00000000
--- a/src/plugins/willing/mode_dynamic.py
+++ /dev/null
@@ -1,233 +0,0 @@
-import asyncio
-import random
-import time
-from typing import Dict
-from .willing_manager import BaseWillingManager
-
-
-class DynamicWillingManager(BaseWillingManager):
- def __init__(self):
- super().__init__()
- self.chat_reply_willing: Dict[str, float] = {} # 存储每个聊天流的回复意愿
- self.chat_high_willing_mode: Dict[str, bool] = {} # 存储每个聊天流是否处于高回复意愿期
- self.chat_msg_count: Dict[str, int] = {} # 存储每个聊天流接收到的消息数量
- self.chat_last_mode_change: Dict[str, float] = {} # 存储每个聊天流上次模式切换的时间
- self.chat_high_willing_duration: Dict[str, int] = {} # 高意愿期持续时间(秒)
- self.chat_low_willing_duration: Dict[str, int] = {} # 低意愿期持续时间(秒)
- self.chat_last_reply_time: Dict[str, float] = {} # 存储每个聊天流上次回复的时间
- self.chat_last_sender_id: Dict[str, str] = {} # 存储每个聊天流上次回复的用户ID
- self.chat_conversation_context: Dict[str, bool] = {} # 标记是否处于对话上下文中
- self._decay_task = None
- self._mode_switch_task = None
-
- async def async_task_starter(self):
- if self._decay_task is None:
- self._decay_task = asyncio.create_task(self._decay_reply_willing())
- if self._mode_switch_task is None:
- self._mode_switch_task = asyncio.create_task(self._mode_switch_check())
-
- async def _decay_reply_willing(self):
- """定期衰减回复意愿"""
- while True:
- await asyncio.sleep(5)
- for chat_id in self.chat_reply_willing:
- is_high_mode = self.chat_high_willing_mode.get(chat_id, False)
- if is_high_mode:
- # 高回复意愿期内轻微衰减
- self.chat_reply_willing[chat_id] = max(0.5, self.chat_reply_willing[chat_id] * 0.95)
- else:
- # 低回复意愿期内正常衰减
- self.chat_reply_willing[chat_id] = max(0, self.chat_reply_willing[chat_id] * 0.8)
-
- async def _mode_switch_check(self):
- """定期检查是否需要切换回复意愿模式"""
- while True:
- current_time = time.time()
- await asyncio.sleep(10) # 每10秒检查一次
-
- for chat_id in self.chat_high_willing_mode:
- last_change_time = self.chat_last_mode_change.get(chat_id, 0)
- is_high_mode = self.chat_high_willing_mode.get(chat_id, False)
-
- # 获取当前模式的持续时间
- if is_high_mode:
- duration = self.chat_high_willing_duration.get(chat_id, 180) # 默认3分钟
- else:
- duration = self.chat_low_willing_duration.get(chat_id, random.randint(300, 1200)) # 默认5-20分钟
-
- # 检查是否需要切换模式
- if current_time - last_change_time > duration:
- self._switch_willing_mode(chat_id)
- elif not is_high_mode and random.random() < 0.1:
- # 低回复意愿期有10%概率随机切换到高回复期
- self._switch_willing_mode(chat_id)
-
- # 检查对话上下文状态是否需要重置
- last_reply_time = self.chat_last_reply_time.get(chat_id, 0)
- if current_time - last_reply_time > 300: # 5分钟无交互,重置对话上下文
- self.chat_conversation_context[chat_id] = False
-
- def _switch_willing_mode(self, chat_id: str):
- """切换聊天流的回复意愿模式"""
- is_high_mode = self.chat_high_willing_mode.get(chat_id, False)
-
- if is_high_mode:
- # 从高回复期切换到低回复期
- self.chat_high_willing_mode[chat_id] = False
- self.chat_reply_willing[chat_id] = 0.1 # 设置为最低回复意愿
- self.chat_low_willing_duration[chat_id] = random.randint(600, 1200) # 10-20分钟
- self.logger.debug(f"聊天流 {chat_id} 切换到低回复意愿期,持续 {self.chat_low_willing_duration[chat_id]} 秒")
- else:
- # 从低回复期切换到高回复期
- self.chat_high_willing_mode[chat_id] = True
- self.chat_reply_willing[chat_id] = 1.0 # 设置为较高回复意愿
- self.chat_high_willing_duration[chat_id] = random.randint(180, 240) # 3-4分钟
- self.logger.debug(
- f"聊天流 {chat_id} 切换到高回复意愿期,持续 {self.chat_high_willing_duration[chat_id]} 秒"
- )
-
- self.chat_last_mode_change[chat_id] = time.time()
- self.chat_msg_count[chat_id] = 0 # 重置消息计数
-
- def _ensure_chat_initialized(self, chat_id: str):
- """确保聊天流的所有数据已初始化"""
- if chat_id not in self.chat_reply_willing:
- self.chat_reply_willing[chat_id] = 0.1
-
- if chat_id not in self.chat_high_willing_mode:
- self.chat_high_willing_mode[chat_id] = False
- self.chat_last_mode_change[chat_id] = time.time()
- self.chat_low_willing_duration[chat_id] = random.randint(300, 1200) # 5-20分钟
-
- if chat_id not in self.chat_msg_count:
- self.chat_msg_count[chat_id] = 0
-
- if chat_id not in self.chat_conversation_context:
- self.chat_conversation_context[chat_id] = False
-
- async def get_reply_probability(self, message_id):
- """改变指定聊天流的回复意愿并返回回复概率"""
- # 获取或创建聊天流
- willing_info = self.ongoing_messages[message_id]
- stream = willing_info.chat
- chat_id = stream.stream_id
- sender_id = str(willing_info.message.message_info.user_info.user_id)
- current_time = time.time()
-
- self._ensure_chat_initialized(chat_id)
-
- # 增加消息计数
- self.chat_msg_count[chat_id] = self.chat_msg_count.get(chat_id, 0) + 1
-
- current_willing = self.chat_reply_willing.get(chat_id, 0)
- is_high_mode = self.chat_high_willing_mode.get(chat_id, False)
- msg_count = self.chat_msg_count.get(chat_id, 0)
- in_conversation_context = self.chat_conversation_context.get(chat_id, False)
-
- # 检查是否是对话上下文中的追问
- last_reply_time = self.chat_last_reply_time.get(chat_id, 0)
- last_sender = self.chat_last_sender_id.get(chat_id, "")
-
- # 如果是同一个人在短时间内(2分钟内)发送消息,且消息数量较少(<=5条),视为追问
- if sender_id and sender_id == last_sender and current_time - last_reply_time < 120 and msg_count <= 5:
- in_conversation_context = True
- self.chat_conversation_context[chat_id] = True
- self.logger.debug("检测到追问 (同一用户), 提高回复意愿")
- current_willing += 0.3
-
- # 特殊情况处理
- if willing_info.is_mentioned_bot:
- current_willing += 0.5
- in_conversation_context = True
- self.chat_conversation_context[chat_id] = True
- self.logger.debug(f"被提及, 当前意愿: {current_willing}")
-
- if willing_info.is_emoji:
- current_willing = self.global_config.emoji_response_penalty * 0.1
- self.logger.debug(f"表情包, 当前意愿: {current_willing}")
-
- # 根据话题兴趣度适当调整
- if willing_info.interested_rate > 0.5:
- current_willing += (
- (willing_info.interested_rate - 0.5) * 0.5 * self.global_config.response_interested_rate_amplifier
- )
-
- # 根据当前模式计算回复概率
- if in_conversation_context:
- # 在对话上下文中,降低基础回复概率
- base_probability = 0.5 if is_high_mode else 0.25
- self.logger.debug(f"处于对话上下文中,基础回复概率: {base_probability}")
- elif is_high_mode:
- # 高回复周期:4-8句话有50%的概率会回复一次
- base_probability = 0.50 if 4 <= msg_count <= 8 else 0.2
- else:
- # 低回复周期:需要最少15句才有30%的概率会回一句
- base_probability = 0.30 if msg_count >= 15 else 0.03 * min(msg_count, 10)
-
- # 考虑回复意愿的影响
- reply_probability = base_probability * current_willing * self.global_config.response_willing_amplifier
-
- # 检查群组权限(如果是群聊)
- if willing_info.group_info:
- if willing_info.group_info.group_id in self.global_config.talk_frequency_down_groups:
- reply_probability = reply_probability / self.global_config.down_frequency_rate
-
- # 限制最大回复概率
- reply_probability = min(reply_probability, 0.75) # 设置最大回复概率为75%
- if reply_probability < 0:
- reply_probability = 0
-
- # 记录当前发送者ID以便后续追踪
- if sender_id:
- self.chat_last_sender_id[chat_id] = sender_id
-
- self.chat_reply_willing[chat_id] = min(current_willing, 3.0)
-
- return reply_probability
-
- async def before_generate_reply_handle(self, message_id):
- """开始思考后降低聊天流的回复意愿"""
- stream = self.ongoing_messages[message_id].chat
- if stream:
- chat_id = stream.stream_id
- self._ensure_chat_initialized(chat_id)
- current_willing = self.chat_reply_willing.get(chat_id, 0)
-
- # 回复后减少回复意愿
- self.chat_reply_willing[chat_id] = max(0.0, current_willing - 0.3)
-
- # 标记为对话上下文中
- self.chat_conversation_context[chat_id] = True
-
- # 记录最后回复时间
- self.chat_last_reply_time[chat_id] = time.time()
-
- # 重置消息计数
- self.chat_msg_count[chat_id] = 0
-
- async def not_reply_handle(self, message_id):
- """决定不回复后提高聊天流的回复意愿"""
- stream = self.ongoing_messages[message_id].chat
- if stream:
- chat_id = stream.stream_id
- self._ensure_chat_initialized(chat_id)
- is_high_mode = self.chat_high_willing_mode.get(chat_id, False)
- current_willing = self.chat_reply_willing.get(chat_id, 0)
- in_conversation_context = self.chat_conversation_context.get(chat_id, False)
-
- # 根据当前模式调整不回复后的意愿增加
- if is_high_mode:
- willing_increase = 0.1
- elif in_conversation_context:
- # 在对话上下文中但决定不回复,小幅增加回复意愿
- willing_increase = 0.15
- else:
- willing_increase = random.uniform(0.05, 0.1)
-
- self.chat_reply_willing[chat_id] = min(2.0, current_willing + willing_increase)
-
- async def bombing_buffer_message_handle(self, message_id):
- return await super().bombing_buffer_message_handle(message_id)
-
- async def after_generate_reply_handle(self, message_id):
- return await super().after_generate_reply_handle(message_id)
diff --git a/src/plugins/willing/mode_llmcheck.py b/src/plugins/willing/mode_llmcheck.py
deleted file mode 100644
index 697621b1..00000000
--- a/src/plugins/willing/mode_llmcheck.py
+++ /dev/null
@@ -1,155 +0,0 @@
-"""
-llmcheck 模式:
-此模式的一些参数不会在配置文件中显示,要修改请在可变参数下修改
-此模式的特点:
-1.在群聊内的连续对话场景下,使用大语言模型来判断回复概率
-2.非连续对话场景,使用mxp模式的意愿管理器(可另外配置)
-3.默认配置的是model_v3,当前参数适用于deepseek-v3-0324
-
-继承自其他模式,实质上仅重写get_reply_probability方法,未来可能重构成一个插件,可方便地组装到其他意愿模式上。
-目前的使用方式是拓展到其他意愿管理模式
-
-"""
-
-import time
-from loguru import logger
-from ..models.utils_model import LLMRequest
-from ...config.config import global_config
-
-# from ..chat.chat_stream import ChatStream
-from ..chat.utils import get_recent_group_detailed_plain_text
-
-# from .willing_manager import BaseWillingManager
-from .mode_mxp import MxpWillingManager
-import re
-from functools import wraps
-
-
-def is_continuous_chat(self, message_id: str):
- # 判断是否是连续对话,出于成本考虑,默认限制5条
- willing_info = self.ongoing_messages[message_id]
- chat_id = willing_info.chat_id
- group_info = willing_info.group_info
- config = self.global_config
- length = 5
- if chat_id:
- chat_talking_text = get_recent_group_detailed_plain_text(chat_id, limit=length, combine=True)
- if group_info:
- if str(config.BOT_QQ) in chat_talking_text:
- return True
- else:
- return False
- return False
-
-
-def llmcheck_decorator(trigger_condition_func):
- def decorator(func):
- @wraps(func)
- def wrapper(self, message_id: str):
- if trigger_condition_func(self, message_id):
- # 满足条件,走llm流程
- return self.get_llmreply_probability(message_id)
- else:
- # 不满足条件,走默认流程
- return func(self, message_id)
-
- return wrapper
-
- return decorator
-
-
-class LlmcheckWillingManager(MxpWillingManager):
- def __init__(self):
- super().__init__()
- self.model_v3 = LLMRequest(model=global_config.llm_normal, temperature=0.3)
-
- async def get_llmreply_probability(self, message_id: str):
- message_info = self.ongoing_messages[message_id]
- chat_id = message_info.chat_id
- config = self.global_config
- # 获取信息的长度
- length = 5
- if message_info.group_info and config:
- if message_info.group_info.group_id not in config.talk_allowed_groups:
- reply_probability = 0
- return reply_probability
-
- current_date = time.strftime("%Y-%m-%d", time.localtime())
- current_time = time.strftime("%H:%M:%S", time.localtime())
- chat_talking_prompt = get_recent_group_detailed_plain_text(chat_id, limit=length, combine=True)
- if not chat_id:
- return 0
-
- # if is_mentioned_bot:
- # return 1.0
- prompt = f"""
- 假设你正在查看一个群聊,你在这个群聊里的网名叫{global_config.BOT_NICKNAME},你还有很多别名: {"/".join(global_config.BOT_ALIAS_NAMES)},
- 现在群里聊天的内容是{chat_talking_prompt},
- 今天是{current_date},现在是{current_time}。
- 综合群内的氛围和你自己之前的发言,给出你认为**最新的消息**需要你回复的概率,数值在0到1之间。请注意,群聊内容杂乱,很多时候对话连续,但很可能不是在和你说话。
- 如果最新的消息和你之前的发言在内容上连续,或者提到了你的名字或者称谓,将其视作明确指向你的互动,给出高于0.8的概率。如果现在是睡眠时间,直接概率为0。如果话题内容与你之前不是紧密相关,请不要给出高于0.1的概率。
- 请注意是判断概率,而不是编写回复内容,
- 仅输出在0到1区间内的概率值,不要给出你的判断依据。
- """
-
- content_check, reasoning_check, _ = await self.model_v3.generate_response(prompt)
- # logger.info(f"{prompt}")
- logger.info(f"{content_check} {reasoning_check}")
- probability = self.extract_marked_probability(content_check)
- # 兴趣系数修正 无关激活效率太高,暂时停用,待新记忆系统上线后调整
- probability += message_info.interested_rate * 0.25
- probability = min(1.0, probability)
- if probability <= 0.1:
- probability = min(0.03, probability)
- if probability >= 0.8:
- probability = max(probability, 0.90)
-
- # 当前表情包理解能力较差,少说就少错
- if message_info.is_emoji:
- probability *= global_config.emoji_response_penalty
-
- return probability
-
- @staticmethod
- def extract_marked_probability(text):
- """提取带标记的概率值 该方法主要用于测试微调prompt阶段"""
- text = text.strip()
- pattern = r"##PROBABILITY_START##(.*?)##PROBABILITY_END##"
- match = re.search(pattern, text, re.DOTALL)
- if match:
- prob_str = match.group(1).strip()
- # 处理百分比(65% → 0.65)
- if "%" in prob_str:
- return float(prob_str.replace("%", "")) / 100
- # 处理分数(2/3 → 0.666...)
- elif "/" in prob_str:
- numerator, denominator = map(float, prob_str.split("/"))
- return numerator / denominator
- # 直接处理小数
- else:
- return float(prob_str)
-
- percent_match = re.search(r"(\d{1,3})%", text) # 65%
- decimal_match = re.search(r"(0\.\d+|1\.0+)", text) # 0.65
- fraction_match = re.search(r"(\d+)/(\d+)", text) # 2/3
- try:
- if percent_match:
- prob = float(percent_match.group(1)) / 100
- elif decimal_match:
- prob = float(decimal_match.group(0))
- elif fraction_match:
- numerator, denominator = map(float, fraction_match.groups())
- prob = numerator / denominator
- else:
- return 0 # 无匹配格式
-
- # 验证范围是否合法
- if 0 <= prob <= 1:
- return prob
- return 0
- except (ValueError, ZeroDivisionError):
- return 0
-
- @llmcheck_decorator(is_continuous_chat)
- def get_reply_probability(self, message_id):
- return super().get_reply_probability(message_id)
diff --git a/src/do_tool/not_used/change_mood.py b/src/tools/not_used/change_mood.py
similarity index 97%
rename from src/do_tool/not_used/change_mood.py
rename to src/tools/not_used/change_mood.py
index 5d1e7f7a..c34bebb9 100644
--- a/src/do_tool/not_used/change_mood.py
+++ b/src/tools/not_used/change_mood.py
@@ -2,7 +2,7 @@ from typing import Any
from src.common.logger_manager import get_logger
from src.config.config import global_config
-from src.do_tool.tool_can_use.base_tool import BaseTool
+from src.tools.tool_can_use.base_tool import BaseTool
from src.manager.mood_manager import mood_manager
logger = get_logger("change_mood_tool")
diff --git a/src/do_tool/not_used/change_relationship.py b/src/tools/not_used/change_relationship.py
similarity index 96%
rename from src/do_tool/not_used/change_relationship.py
rename to src/tools/not_used/change_relationship.py
index 96f512e5..b038a3e6 100644
--- a/src/do_tool/not_used/change_relationship.py
+++ b/src/tools/not_used/change_relationship.py
@@ -1,6 +1,6 @@
from typing import Any
from src.common.logger_manager import get_logger
-from src.do_tool.tool_can_use.base_tool import BaseTool
+from src.tools.tool_can_use.base_tool import BaseTool
logger = get_logger("relationship_tool")
diff --git a/src/do_tool/not_used/get_memory.py b/src/tools/not_used/get_memory.py
similarity index 94%
rename from src/do_tool/not_used/get_memory.py
rename to src/tools/not_used/get_memory.py
index 481942da..2f40d381 100644
--- a/src/do_tool/not_used/get_memory.py
+++ b/src/tools/not_used/get_memory.py
@@ -1,5 +1,5 @@
-from src.do_tool.tool_can_use.base_tool import BaseTool
-from src.plugins.memory_system.Hippocampus import HippocampusManager
+from src.tools.tool_can_use.base_tool import BaseTool
+from src.chat.memory_system.Hippocampus import HippocampusManager
from src.common.logger import get_module_logger
from typing import Dict, Any
diff --git a/src/do_tool/not_used/mid_chat_mem.py b/src/tools/not_used/mid_chat_mem.py
similarity index 95%
rename from src/do_tool/not_used/mid_chat_mem.py
rename to src/tools/not_used/mid_chat_mem.py
index 0340df13..fc64ab29 100644
--- a/src/do_tool/not_used/mid_chat_mem.py
+++ b/src/tools/not_used/mid_chat_mem.py
@@ -1,4 +1,4 @@
-from src.do_tool.tool_can_use.base_tool import BaseTool
+from src.tools.tool_can_use.base_tool import BaseTool
from src.common.logger import get_module_logger
from typing import Any
diff --git a/src/do_tool/not_used/send_emoji.py b/src/tools/not_used/send_emoji.py
similarity index 93%
rename from src/do_tool/not_used/send_emoji.py
rename to src/tools/not_used/send_emoji.py
index d2d00a92..698ba2a7 100644
--- a/src/do_tool/not_used/send_emoji.py
+++ b/src/tools/not_used/send_emoji.py
@@ -1,4 +1,4 @@
-from src.do_tool.tool_can_use.base_tool import BaseTool
+from src.tools.tool_can_use.base_tool import BaseTool
from src.common.logger import get_module_logger
from typing import Any
diff --git a/src/do_tool/tool_can_use/README.md b/src/tools/tool_can_use/README.md
similarity index 96%
rename from src/do_tool/tool_can_use/README.md
rename to src/tools/tool_can_use/README.md
index 0b746b4e..ef6760b5 100644
--- a/src/do_tool/tool_can_use/README.md
+++ b/src/tools/tool_can_use/README.md
@@ -9,7 +9,7 @@
每个工具应该继承 `BaseTool` 基类并实现必要的属性和方法:
```python
-from src.do_tool.tool_can_use.base_tool import BaseTool, register_tool
+from src.tools.tool_can_use.base_tool import BaseTool, register_tool
class MyNewTool(BaseTool):
# 工具名称,必须唯一
@@ -86,7 +86,7 @@ register_tool(MyNewTool)
## 使用示例
```python
-from src.do_tool.tool_use import ToolUser
+from src.tools.tool_use import ToolUser
# 创建工具用户
tool_user = ToolUser()
diff --git a/src/do_tool/tool_can_use/__init__.py b/src/tools/tool_can_use/__init__.py
similarity index 86%
rename from src/do_tool/tool_can_use/__init__.py
rename to src/tools/tool_can_use/__init__.py
index a7ea17ab..14bae04c 100644
--- a/src/do_tool/tool_can_use/__init__.py
+++ b/src/tools/tool_can_use/__init__.py
@@ -1,4 +1,4 @@
-from src.do_tool.tool_can_use.base_tool import (
+from src.tools.tool_can_use.base_tool import (
BaseTool,
register_tool,
discover_tools,
diff --git a/src/do_tool/tool_can_use/base_tool.py b/src/tools/tool_can_use/base_tool.py
similarity index 97%
rename from src/do_tool/tool_can_use/base_tool.py
rename to src/tools/tool_can_use/base_tool.py
index 15e07a9c..f916b691 100644
--- a/src/do_tool/tool_can_use/base_tool.py
+++ b/src/tools/tool_can_use/base_tool.py
@@ -86,7 +86,7 @@ def discover_tools():
continue
# 导入模块
- module = importlib.import_module(f"src.do_tool.{package_name}.{module_name}")
+ module = importlib.import_module(f"src.tools.{package_name}.{module_name}")
# 查找模块中的工具类
for _, obj in inspect.getmembers(module):
diff --git a/src/do_tool/tool_can_use/compare_numbers_tool.py b/src/tools/tool_can_use/compare_numbers_tool.py
similarity index 96%
rename from src/do_tool/tool_can_use/compare_numbers_tool.py
rename to src/tools/tool_can_use/compare_numbers_tool.py
index 2bb292a1..72c7d7d1 100644
--- a/src/do_tool/tool_can_use/compare_numbers_tool.py
+++ b/src/tools/tool_can_use/compare_numbers_tool.py
@@ -1,4 +1,4 @@
-from src.do_tool.tool_can_use.base_tool import BaseTool
+from src.tools.tool_can_use.base_tool import BaseTool
from src.common.logger import get_module_logger
from typing import Any
diff --git a/src/do_tool/tool_can_use/get_knowledge.py b/src/tools/tool_can_use/get_knowledge.py
similarity index 97%
rename from src/do_tool/tool_can_use/get_knowledge.py
rename to src/tools/tool_can_use/get_knowledge.py
index 90a44655..65acd55c 100644
--- a/src/do_tool/tool_can_use/get_knowledge.py
+++ b/src/tools/tool_can_use/get_knowledge.py
@@ -1,5 +1,5 @@
-from src.do_tool.tool_can_use.base_tool import BaseTool
-from src.plugins.chat.utils import get_embedding
+from src.tools.tool_can_use.base_tool import BaseTool
+from src.chat.utils.utils import get_embedding
from src.common.database import db
from src.common.logger_manager import get_logger
from typing import Any, Union
diff --git a/src/do_tool/tool_can_use/get_time_date.py b/src/tools/tool_can_use/get_time_date.py
similarity index 95%
rename from src/do_tool/tool_can_use/get_time_date.py
rename to src/tools/tool_can_use/get_time_date.py
index 1cb23fdb..8b098674 100644
--- a/src/do_tool/tool_can_use/get_time_date.py
+++ b/src/tools/tool_can_use/get_time_date.py
@@ -1,4 +1,4 @@
-from src.do_tool.tool_can_use.base_tool import BaseTool
+from src.tools.tool_can_use.base_tool import BaseTool
from src.common.logger_manager import get_logger
from typing import Dict, Any
from datetime import datetime
diff --git a/src/do_tool/tool_can_use/lpmm_get_knowledge.py b/src/tools/tool_can_use/lpmm_get_knowledge.py
similarity index 97%
rename from src/do_tool/tool_can_use/lpmm_get_knowledge.py
rename to src/tools/tool_can_use/lpmm_get_knowledge.py
index a4ded910..f7c0bd75 100644
--- a/src/do_tool/tool_can_use/lpmm_get_knowledge.py
+++ b/src/tools/tool_can_use/lpmm_get_knowledge.py
@@ -1,10 +1,10 @@
-from src.do_tool.tool_can_use.base_tool import BaseTool
-from src.plugins.chat.utils import get_embedding
+from src.tools.tool_can_use.base_tool import BaseTool
+from src.chat.utils.utils import get_embedding
# from src.common.database import db
from src.common.logger_manager import get_logger
from typing import Dict, Any
-from src.plugins.knowledge.knowledge_lib import qa_manager
+from src.chat.knowledge.knowledge_lib import qa_manager
logger = get_logger("lpmm_get_knowledge_tool")
diff --git a/src/do_tool/tool_can_use/rename_person_tool.py b/src/tools/tool_can_use/rename_person_tool.py
similarity index 97%
rename from src/do_tool/tool_can_use/rename_person_tool.py
rename to src/tools/tool_can_use/rename_person_tool.py
index 3084a94c..e853a40b 100644
--- a/src/do_tool/tool_can_use/rename_person_tool.py
+++ b/src/tools/tool_can_use/rename_person_tool.py
@@ -1,5 +1,5 @@
-from src.do_tool.tool_can_use.base_tool import BaseTool
-from src.plugins.person_info.person_info import person_info_manager
+from src.tools.tool_can_use.base_tool import BaseTool, register_tool
+from src.chat.person_info.person_info import person_info_manager
from src.common.logger_manager import get_logger
import time
diff --git a/src/do_tool/tool_use.py b/src/tools/tool_use.py
similarity index 94%
rename from src/do_tool/tool_use.py
rename to src/tools/tool_use.py
index b2f59cc8..c55170b8 100644
--- a/src/do_tool/tool_use.py
+++ b/src/tools/tool_use.py
@@ -1,13 +1,13 @@
-from src.plugins.models.utils_model import LLMRequest
+from src.chat.models.utils_model import LLMRequest
from src.config.config import global_config
import json
from src.common.logger_manager import get_logger
-from src.do_tool.tool_can_use import get_all_tool_definitions, get_tool_instance
+from src.tools.tool_can_use import get_all_tool_definitions, get_tool_instance
import traceback
-from src.plugins.person_info.relationship_manager import relationship_manager
-from src.plugins.chat.utils import parse_text_timestamps
-from src.plugins.chat.chat_stream import ChatStream
-from src.heart_flow.observation import ChattingObservation
+from src.chat.person_info.relationship_manager import relationship_manager
+from src.chat.utils.utils import parse_text_timestamps
+from src.chat.message_receive.chat_stream import ChatStream
+from src.chat.heart_flow.observation.chatting_observation import ChattingObservation
logger = get_logger("tool_use")
diff --git a/template/bot_config_meta.toml b/template/bot_config_meta.toml
index 459b7026..c3541baa 100644
--- a/template/bot_config_meta.toml
+++ b/template/bot_config_meta.toml
@@ -63,36 +63,6 @@ describe = "外貌特征描述,该选项还在调试中,暂时未生效"
important = false
can_edit = true
-[schedule.enable_schedule_gen]
-describe = "是否启用日程表"
-important = false
-can_edit = true
-
-[schedule.enable_schedule_interaction]
-describe = "日程表是否影响回复模式"
-important = false
-can_edit = true
-
-[schedule.prompt_schedule_gen]
-describe = "用几句话描述描述性格特点或行动规律,这个特征会用来生成日程表"
-important = false
-can_edit = true
-
-[schedule.schedule_doing_update_interval]
-describe = "日程表更新间隔,单位秒"
-important = false
-can_edit = true
-
-[schedule.schedule_temperature]
-describe = "日程表温度,建议0.1-0.5"
-important = false
-can_edit = true
-
-[schedule.time_zone]
-describe = "时区设置,可以解决运行电脑时区和国内时区不同的情况,或者模拟国外留学生日程"
-important = false
-can_edit = true
-
[platforms.nonebot-qq]
describe = "nonebot-qq适配器提供的链接"
important = true
diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml
index 1ed9e034..aa3af76d 100644
--- a/template/bot_config_template.toml
+++ b/template/bot_config_template.toml
@@ -1,5 +1,5 @@
[inner]
-version = "1.6.2.4"
+version = "1.7.1"
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
#如果你想要修改配置文件,请在修改后将version的值进行变更
@@ -44,6 +44,10 @@ personality_sides = [
]# 条数任意,不能为0, 该选项还在调试中,可能未完全生效
personality_detail_level = 0 # 人设消息注入 prompt 详细等级 (0: 采用默认配置, 1: 核心/随机细节, 2: 核心+随机侧面/全部细节, 3: 全部)
+# 表达方式
+expression_style = "描述麦麦说话的表达风格,表达习惯"
+
+
[identity] #アイデンティティがない 生まれないらららら
# 兴趣爱好 未完善,有些条目未使用
identity_detail = [
@@ -55,23 +59,15 @@ age = 20 # 年龄 单位岁
gender = "男" # 性别
appearance = "用几句话描述外貌特征" # 外貌特征 该选项还在调试中,暂时未生效
-[schedule]
-enable_schedule_gen = true # 是否启用日程表
-enable_schedule_interaction = true # 日程表是否影响回复模式
-prompt_schedule_gen = "用几句话描述描述性格特点或行动规律,这个特征会用来生成日程表"
-schedule_doing_update_interval = 900 # 日程表更新间隔 单位秒
-schedule_temperature = 0.1 # 日程表温度,建议0.1-0.5
-time_zone = "Asia/Shanghai" # 给你的机器人设置时区,可以解决运行电脑时区和国内时区不同的情况,或者模拟国外留学生日程
-
[platforms] # 必填项目,填写每个平台适配器提供的链接
-nonebot-qq="http://127.0.0.1:18002/api/message"
+qq="http://127.0.0.1:18002/api/message"
[chat] #麦麦的聊天通用设置
-allow_focus_mode = true # 是否允许专注聊天状态
+allow_focus_mode = false # 是否允许专注聊天状态
# 是否启用heart_flowC(HFC)模式
# 启用后麦麦会自主选择进入heart_flowC模式(持续一段时间),进行主动的观察和回复,并给出回复,比较消耗token
-base_normal_chat_num = 8 # 最多允许多少个群进行普通聊天
-base_focused_chat_num = 5 # 最多允许多少个群进行专注聊天
+base_normal_chat_num = 999 # 最多允许多少个群进行普通聊天
+base_focused_chat_num = 4 # 最多允许多少个群进行专注聊天
allow_remove_duplicates = true # 是否开启心流去重(如果发现心流截断问题严重可尝试关闭)
observation_context_size = 15 # 观察到的最长上下文大小,建议15,太短太长都会导致脑袋尖尖
@@ -97,7 +93,7 @@ model_normal_probability = 0.3 # 麦麦回答时选择一般模型 模型的概
emoji_chance = 0.2 # 麦麦一般回复时使用表情包的概率,设置为1让麦麦自己决定发不发
thinking_timeout = 100 # 麦麦最长思考时间,超过这个时间的思考会放弃(往往是api反应太慢)
-willing_mode = "classical" # 回复意愿模式 —— 经典模式:classical,动态模式:dynamic,mxp模式:mxp,自定义模式:custom(需要你自己实现)
+willing_mode = "classical" # 回复意愿模式 —— 经典模式:classical,mxp模式:mxp,自定义模式:custom(需要你自己实现)
response_willing_amplifier = 1 # 麦麦回复意愿放大系数,一般为1
response_interested_rate_amplifier = 1 # 麦麦回复兴趣度放大系数,听到记忆里的内容时放大系数
down_frequency_rate = 3 # 降低回复频率的群组回复意愿降低系数 除法
diff --git a/template/lpmm_config_template.toml b/template/lpmm_config_template.toml
index 745cbaaf..5bf24732 100644
--- a/template/lpmm_config_template.toml
+++ b/template/lpmm_config_template.toml
@@ -54,7 +54,7 @@ res_top_k = 3 # 最终提供的文段TopK
[persistence]
# 持久化配置(存储中间数据,防止重复计算)
data_root_path = "data" # 数据根目录
-raw_data_path = "data/imported_lpmm_data" # 原始数据路径
+imported_data_path = "data/imported_lpmm_data" # 转换为json的raw文件数据路径
openie_data_path = "data/openie" # OpenIE数据路径
embedding_data_dir = "data/embedding" # 嵌入数据目录
rag_data_dir = "data/rag" # RAG数据目录
diff --git a/template/template.env b/template/template.env
index 11b418b8..becdcd7d 100644
--- a/template/template.env
+++ b/template/template.env
@@ -1,9 +1,6 @@
HOST=127.0.0.1
PORT=8000
-# 插件配置
-PLUGINS=["src2.plugins.chat"]
-
# 默认配置
# 如果工作在Docker下,请改成 MONGODB_HOST=mongodb
MONGODB_HOST=127.0.0.1