fix:修复零散小问题
This commit is contained in:
6
bot.py
6
bot.py
@@ -11,7 +11,6 @@ from rich.traceback import install
|
|||||||
|
|
||||||
# 最早期初始化日志系统,确保所有后续模块都使用正确的日志格式
|
# 最早期初始化日志系统,确保所有后续模块都使用正确的日志格式
|
||||||
from src.common.logger import initialize_logging, get_logger
|
from src.common.logger import initialize_logging, get_logger
|
||||||
from src.common.crash_logger import install_crash_handler
|
|
||||||
from src.main import MainSystem
|
from src.main import MainSystem
|
||||||
from src.manager.async_task_manager import async_task_manager
|
from src.manager.async_task_manager import async_task_manager
|
||||||
|
|
||||||
@@ -200,11 +199,8 @@ def raw_main():
|
|||||||
if platform.system().lower() != "windows":
|
if platform.system().lower() != "windows":
|
||||||
time.tzset()
|
time.tzset()
|
||||||
|
|
||||||
# 安装崩溃日志处理器
|
|
||||||
install_crash_handler()
|
|
||||||
|
|
||||||
check_eula()
|
check_eula()
|
||||||
print("检查EULA和隐私条款完成")
|
logger.info("检查EULA和隐私条款完成")
|
||||||
|
|
||||||
easter_egg()
|
easter_egg()
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
立即重新加载日志配置
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
# 添加src目录到路径
|
|
||||||
src_path = Path(__file__).parent / "src"
|
|
||||||
sys.path.insert(0, str(src_path))
|
|
||||||
|
|
||||||
from common.logger import reload_log_config # noqa: E402
|
|
||||||
|
|
||||||
print("🔄 重新加载日志配置...")
|
|
||||||
reload_log_config()
|
|
||||||
print("✅ 配置已重新加载!faiss日志已被屏蔽。")
|
|
||||||
@@ -52,9 +52,6 @@ async def _process_relationship(message: MessageRecv) -> None:
|
|||||||
if not is_known:
|
if not is_known:
|
||||||
logger.info(f"首次认识用户: {nickname}")
|
logger.info(f"首次认识用户: {nickname}")
|
||||||
await relationship_manager.first_knowing_some_one(platform, user_id, nickname, cardname)
|
await relationship_manager.first_knowing_some_one(platform, user_id, nickname, cardname)
|
||||||
# elif not await relationship_manager.is_qved_name(platform, user_id):
|
|
||||||
# logger.info(f"给用户({nickname},{cardname})取名: {nickname}")
|
|
||||||
# await relationship_manager.first_knowing_some_one(platform, user_id, nickname, cardname, "")
|
|
||||||
|
|
||||||
|
|
||||||
async def _calculate_interest(message: MessageRecv) -> Tuple[float, bool]:
|
async def _calculate_interest(message: MessageRecv) -> Tuple[float, bool]:
|
||||||
@@ -93,28 +90,6 @@ async def _calculate_interest(message: MessageRecv) -> Tuple[float, bool]:
|
|||||||
return interested_rate, is_mentioned
|
return interested_rate, is_mentioned
|
||||||
|
|
||||||
|
|
||||||
# def _get_message_type(message: MessageRecv) -> str:
|
|
||||||
# """获取消息类型
|
|
||||||
|
|
||||||
# Args:
|
|
||||||
# message: 消息对象
|
|
||||||
|
|
||||||
# Returns:
|
|
||||||
# str: 消息类型
|
|
||||||
# """
|
|
||||||
# if message.message_segment.type != "seglist":
|
|
||||||
# return message.message_segment.type
|
|
||||||
|
|
||||||
# if (
|
|
||||||
# isinstance(message.message_segment.data, list)
|
|
||||||
# and all(isinstance(x, Seg) for x in message.message_segment.data)
|
|
||||||
# and len(message.message_segment.data) == 1
|
|
||||||
# ):
|
|
||||||
# return message.message_segment.data[0].type
|
|
||||||
|
|
||||||
# return "seglist"
|
|
||||||
|
|
||||||
|
|
||||||
def _check_ban_words(text: str, chat: ChatStream, userinfo: UserInfo) -> bool:
|
def _check_ban_words(text: str, chat: ChatStream, userinfo: UserInfo) -> bool:
|
||||||
"""检查消息是否包含过滤词
|
"""检查消息是否包含过滤词
|
||||||
|
|
||||||
@@ -212,7 +187,7 @@ class HeartFCMessageReceiver:
|
|||||||
logger.info(f"[{mes_name}]{userinfo.user_nickname}:{message.processed_plain_text}")
|
logger.info(f"[{mes_name}]{userinfo.user_nickname}:{message.processed_plain_text}")
|
||||||
|
|
||||||
# 8. 关系处理
|
# 8. 关系处理
|
||||||
if global_config.relationship.enable_relationship and global_config.relationship.give_name:
|
if global_config.relationship.enable_relationship:
|
||||||
await _process_relationship(message)
|
await _process_relationship(message)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -98,6 +98,11 @@ class ActionManager:
|
|||||||
动作管理器,用于管理各种类型的动作
|
动作管理器,用于管理各种类型的动作
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# 类常量
|
||||||
|
DEFAULT_RANDOM_PROBABILITY = 0.3
|
||||||
|
DEFAULT_MODE = "all"
|
||||||
|
DEFAULT_ACTIVATION_TYPE = "always"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""初始化动作管理器"""
|
"""初始化动作管理器"""
|
||||||
# 所有注册的动作集合
|
# 所有注册的动作集合
|
||||||
@@ -108,9 +113,6 @@ class ActionManager:
|
|||||||
# 默认动作集,仅作为快照,用于恢复默认
|
# 默认动作集,仅作为快照,用于恢复默认
|
||||||
self._default_actions: Dict[str, ActionInfo] = {}
|
self._default_actions: Dict[str, ActionInfo] = {}
|
||||||
|
|
||||||
# 加载所有已注册动作
|
|
||||||
self._load_registered_actions()
|
|
||||||
|
|
||||||
# 加载插件动作
|
# 加载插件动作
|
||||||
self._load_plugin_actions()
|
self._load_plugin_actions()
|
||||||
|
|
||||||
@@ -120,103 +122,11 @@ class ActionManager:
|
|||||||
# 添加系统核心动作
|
# 添加系统核心动作
|
||||||
self._add_system_core_actions()
|
self._add_system_core_actions()
|
||||||
|
|
||||||
def _load_registered_actions(self) -> None:
|
|
||||||
"""
|
|
||||||
加载所有通过装饰器注册的动作
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# 从组件注册中心获取所有已注册的action
|
|
||||||
from src.plugin_system.core.component_registry import component_registry
|
|
||||||
|
|
||||||
action_registry = component_registry.get_action_registry()
|
|
||||||
|
|
||||||
# 从action_registry获取所有已注册动作
|
|
||||||
for action_name, action_class in action_registry.items():
|
|
||||||
# 获取动作相关信息
|
|
||||||
|
|
||||||
# 不读取插件动作和基类
|
|
||||||
if action_name == "base_action" or action_name == "plugin_action":
|
|
||||||
continue
|
|
||||||
|
|
||||||
action_description: str = getattr(action_class, "action_description", "")
|
|
||||||
action_parameters: dict[str:str] = getattr(action_class, "action_parameters", {})
|
|
||||||
action_require: list[str] = getattr(action_class, "action_require", [])
|
|
||||||
associated_types: list[str] = getattr(action_class, "associated_types", [])
|
|
||||||
is_enabled: bool = getattr(action_class, "enable_plugin", True)
|
|
||||||
|
|
||||||
# 获取激活类型相关属性
|
|
||||||
focus_activation_type_attr = getattr(action_class, "focus_activation_type", "always")
|
|
||||||
normal_activation_type_attr = getattr(action_class, "normal_activation_type", "always")
|
|
||||||
|
|
||||||
# 处理枚举值,提取.value
|
|
||||||
focus_activation_type = (
|
|
||||||
focus_activation_type_attr.value
|
|
||||||
if hasattr(focus_activation_type_attr, "value")
|
|
||||||
else str(focus_activation_type_attr)
|
|
||||||
)
|
|
||||||
normal_activation_type = (
|
|
||||||
normal_activation_type_attr.value
|
|
||||||
if hasattr(normal_activation_type_attr, "value")
|
|
||||||
else str(normal_activation_type_attr)
|
|
||||||
)
|
|
||||||
|
|
||||||
# 其他属性
|
|
||||||
random_probability: float = getattr(action_class, "random_activation_probability", 0.3)
|
|
||||||
llm_judge_prompt: str = getattr(action_class, "llm_judge_prompt", "")
|
|
||||||
activation_keywords: list[str] = getattr(action_class, "activation_keywords", [])
|
|
||||||
keyword_case_sensitive: bool = getattr(action_class, "keyword_case_sensitive", False)
|
|
||||||
|
|
||||||
# 处理模式启用属性
|
|
||||||
mode_enable_attr = getattr(action_class, "mode_enable", "all")
|
|
||||||
mode_enable = mode_enable_attr.value if hasattr(mode_enable_attr, "value") else str(mode_enable_attr)
|
|
||||||
|
|
||||||
# 获取并行执行属性
|
|
||||||
parallel_action: bool = getattr(action_class, "parallel_action", False)
|
|
||||||
|
|
||||||
if action_name and action_description:
|
|
||||||
# 创建动作信息字典
|
|
||||||
action_info = {
|
|
||||||
"description": action_description,
|
|
||||||
"parameters": action_parameters,
|
|
||||||
"require": action_require,
|
|
||||||
"associated_types": associated_types,
|
|
||||||
"focus_activation_type": focus_activation_type,
|
|
||||||
"normal_activation_type": normal_activation_type,
|
|
||||||
"random_probability": random_probability,
|
|
||||||
"llm_judge_prompt": llm_judge_prompt,
|
|
||||||
"activation_keywords": activation_keywords,
|
|
||||||
"keyword_case_sensitive": keyword_case_sensitive,
|
|
||||||
"mode_enable": mode_enable,
|
|
||||||
"parallel_action": parallel_action,
|
|
||||||
}
|
|
||||||
|
|
||||||
# 添加到所有已注册的动作
|
|
||||||
self._registered_actions[action_name] = action_info
|
|
||||||
|
|
||||||
# 添加到默认动作(如果启用插件)
|
|
||||||
if is_enabled:
|
|
||||||
self._default_actions[action_name] = action_info
|
|
||||||
|
|
||||||
# logger.info(f"所有注册动作: {list(self._registered_actions.keys())}")
|
|
||||||
# logger.info(f"默认动作: {list(self._default_actions.keys())}")
|
|
||||||
# for action_name, action_info in self._default_actions.items():
|
|
||||||
# logger.info(f"动作名称: {action_name}, 动作信息: {action_info}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"加载已注册动作失败: {e}")
|
|
||||||
|
|
||||||
def _load_plugin_actions(self) -> None:
|
def _load_plugin_actions(self) -> None:
|
||||||
"""
|
"""
|
||||||
加载所有插件目录中的动作
|
加载所有插件目录中的动作
|
||||||
|
|
||||||
注意:插件动作的实际导入已经在main.py中完成,这里只需要从action_registry获取
|
|
||||||
同时也从新插件系统的component_registry获取Action组件
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 从旧的action_registry获取插件动作
|
|
||||||
self._load_registered_actions()
|
|
||||||
logger.debug("从旧注册表加载插件动作成功")
|
|
||||||
|
|
||||||
# 从新插件系统获取Action组件
|
# 从新插件系统获取Action组件
|
||||||
self._load_plugin_system_actions()
|
self._load_plugin_system_actions()
|
||||||
logger.debug("从新插件系统加载Action组件成功")
|
logger.debug("从新插件系统加载Action组件成功")
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
import sys
|
|
||||||
import traceback
|
|
||||||
import logging
|
|
||||||
from pathlib import Path
|
|
||||||
from logging.handlers import RotatingFileHandler
|
|
||||||
|
|
||||||
|
|
||||||
def setup_crash_logger():
|
|
||||||
"""设置崩溃日志记录器"""
|
|
||||||
# 创建logs/crash目录(如果不存在)
|
|
||||||
crash_log_dir = Path("logs/crash")
|
|
||||||
crash_log_dir.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
# 创建日志记录器
|
|
||||||
crash_logger = logging.getLogger("crash_logger")
|
|
||||||
crash_logger.setLevel(logging.ERROR)
|
|
||||||
|
|
||||||
# 设置日志格式
|
|
||||||
formatter = logging.Formatter(
|
|
||||||
"%(asctime)s - %(name)s - %(levelname)s\n异常类型: %(exc_info)s\n详细信息:\n%(message)s\n-------------------\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
# 创建按大小轮转的文件处理器(最大10MB,保留5个备份)
|
|
||||||
log_file = crash_log_dir / "crash.log"
|
|
||||||
file_handler = RotatingFileHandler(
|
|
||||||
log_file,
|
|
||||||
maxBytes=10 * 1024 * 1024, # 10MB
|
|
||||||
backupCount=5,
|
|
||||||
encoding="utf-8",
|
|
||||||
)
|
|
||||||
file_handler.setFormatter(formatter)
|
|
||||||
crash_logger.addHandler(file_handler)
|
|
||||||
|
|
||||||
return crash_logger
|
|
||||||
|
|
||||||
|
|
||||||
def log_crash(exc_type, exc_value, exc_traceback):
|
|
||||||
"""记录崩溃信息到日志文件"""
|
|
||||||
if exc_type is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
# 获取崩溃日志记录器
|
|
||||||
crash_logger = logging.getLogger("crash_logger")
|
|
||||||
|
|
||||||
# 获取完整的异常堆栈信息
|
|
||||||
stack_trace = "".join(traceback.format_exception(exc_type, exc_value, exc_traceback))
|
|
||||||
|
|
||||||
# 记录崩溃信息
|
|
||||||
crash_logger.error(stack_trace, exc_info=(exc_type, exc_value, exc_traceback))
|
|
||||||
|
|
||||||
|
|
||||||
def install_crash_handler():
|
|
||||||
"""安装全局异常处理器"""
|
|
||||||
# 设置崩溃日志记录器
|
|
||||||
setup_crash_logger()
|
|
||||||
|
|
||||||
# 保存原始的异常处理器
|
|
||||||
original_hook = sys.excepthook
|
|
||||||
|
|
||||||
def exception_handler(exc_type, exc_value, exc_traceback):
|
|
||||||
"""全局异常处理器"""
|
|
||||||
# 记录崩溃信息
|
|
||||||
log_crash(exc_type, exc_value, exc_traceback)
|
|
||||||
|
|
||||||
# 调用原始的异常处理器
|
|
||||||
original_hook(exc_type, exc_value, exc_traceback)
|
|
||||||
|
|
||||||
# 设置全局异常处理器
|
|
||||||
sys.excepthook = exception_handler
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
from typing import Any
|
|
||||||
|
|
||||||
from src.common.logger import get_logger
|
|
||||||
from src.config.config import global_config
|
|
||||||
from src.tools.tool_can_use.base_tool import BaseTool
|
|
||||||
from src.manager.mood_manager import mood_manager
|
|
||||||
|
|
||||||
logger = get_logger("change_mood_tool")
|
|
||||||
|
|
||||||
|
|
||||||
class ChangeMoodTool(BaseTool):
|
|
||||||
"""改变心情的工具"""
|
|
||||||
|
|
||||||
name = "change_mood"
|
|
||||||
description = "根据收到的内容和自身回复的内容,改变心情,当你回复了别人的消息,你可以使用这个工具"
|
|
||||||
parameters = {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"text": {"type": "string", "description": "引起你改变心情的文本"},
|
|
||||||
"response_set": {"type": "list", "description": "你对文本的回复"},
|
|
||||||
},
|
|
||||||
"required": ["text", "response_set"],
|
|
||||||
}
|
|
||||||
|
|
||||||
async def execute(self, function_args: dict[str, Any], message_txt: str = "") -> dict[str, Any]:
|
|
||||||
"""执行心情改变
|
|
||||||
|
|
||||||
Args:
|
|
||||||
function_args: 工具参数
|
|
||||||
message_txt: 原始消息文本
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: 工具执行结果
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
response_set = function_args.get("response_set")
|
|
||||||
_message_processed_plain_text = function_args.get("text")
|
|
||||||
|
|
||||||
# gpt = ResponseGenerator()
|
|
||||||
|
|
||||||
if response_set is None:
|
|
||||||
response_set = ["你还没有回复"]
|
|
||||||
|
|
||||||
_ori_response = ",".join(response_set)
|
|
||||||
# _stance, emotion = await gpt._get_emotion_tags(ori_response, message_processed_plain_text)
|
|
||||||
emotion = "平静"
|
|
||||||
mood_manager.update_mood_from_emotion(emotion, global_config.mood.mood_intensity_factor)
|
|
||||||
return {"name": "change_mood", "content": f"你的心情刚刚变化了,现在的心情是: {emotion}"}
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"心情改变工具执行失败: {str(e)}")
|
|
||||||
return {"name": "change_mood", "content": f"心情改变失败: {str(e)}"}
|
|
||||||
|
|
||||||
|
|
||||||
# 注册工具
|
|
||||||
# register_tool(ChangeMoodTool)
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
from typing import Any
|
|
||||||
from src.common.logger import get_logger
|
|
||||||
from src.tools.tool_can_use.base_tool import BaseTool
|
|
||||||
|
|
||||||
|
|
||||||
logger = get_logger("relationship_tool")
|
|
||||||
|
|
||||||
|
|
||||||
class RelationshipTool(BaseTool):
|
|
||||||
name = "change_relationship"
|
|
||||||
description = "根据收到的文本和回复内容,修改与特定用户的关系值,当你回复了别人的消息,你可以使用这个工具"
|
|
||||||
parameters = {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"text": {"type": "string", "description": "收到的文本"},
|
|
||||||
"changed_value": {"type": "number", "description": "变更值"},
|
|
||||||
"reason": {"type": "string", "description": "变更原因"},
|
|
||||||
},
|
|
||||||
"required": ["text", "changed_value", "reason"],
|
|
||||||
}
|
|
||||||
|
|
||||||
async def execute(self, function_args: dict[str, Any], message_txt: str = "") -> dict:
|
|
||||||
"""执行工具功能
|
|
||||||
|
|
||||||
Args:
|
|
||||||
function_args: 包含工具参数的字典
|
|
||||||
message_txt: 原始消息文本
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: 包含执行结果的字典
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
text = function_args.get("text")
|
|
||||||
changed_value = function_args.get("changed_value")
|
|
||||||
reason = function_args.get("reason")
|
|
||||||
|
|
||||||
return {"content": f"因为你刚刚因为{reason},所以你和发[{text}]这条消息的人的关系值变化为{changed_value}"}
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"修改关系值时发生错误: {str(e)}")
|
|
||||||
return {"content": f"修改关系值失败: {str(e)}"}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
[inner]
|
[inner]
|
||||||
version = "2.19.0"
|
version = "2.20.0"
|
||||||
|
|
||||||
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
||||||
#如果你想要修改配置文件,请在修改后将version的值进行变更
|
#如果你想要修改配置文件,请在修改后将version的值进行变更
|
||||||
@@ -190,7 +190,7 @@ color_text = "title" # 日志文本颜色,可选none,title,full
|
|||||||
log_level = "INFO"
|
log_level = "INFO"
|
||||||
|
|
||||||
# 第三方库日志控制
|
# 第三方库日志控制
|
||||||
suppress_libraries = ["faiss","httpx", "urllib3", "asyncio", "websockets", "httpcore", "requests", "peewee", "openai"] # 完全屏蔽的库
|
suppress_libraries = ["faiss","httpx", "urllib3", "asyncio", "websockets", "httpcore", "requests", "peewee", "openai","uvicorn"] # 完全屏蔽的库
|
||||||
library_log_levels = { "aiohttp" = "WARNING"} # 设置特定库的日志级别
|
library_log_levels = { "aiohttp" = "WARNING"} # 设置特定库的日志级别
|
||||||
|
|
||||||
#下面的模型若使用硅基流动则不需要更改,使用ds官方则改成.env自定义的宏,使用自定义模型则选择定位相似的模型自己填写
|
#下面的模型若使用硅基流动则不需要更改,使用ds官方则改成.env自定义的宏,使用自定义模型则选择定位相似的模型自己填写
|
||||||
|
|||||||
Reference in New Issue
Block a user