from src.common.logger import LogConfig, WILLING_STYLE_CONFIG, LoguruLogger, get_module_logger from dataclasses import dataclass from ...config.config import global_config, BotConfig from ..chat.chat_stream import ChatStream, GroupInfo from ..chat.message import MessageRecv from ..person_info.person_info import person_info_manager, PersonInfoManager from abc import ABC, abstractmethod import importlib from typing import Dict, Optional import asyncio """ 基类方法概览: 以下8个方法是你必须在子类重写的(哪怕什么都不干): async_task_starter 在程序启动时执行,在其中用asyncio.create_task启动你想要执行的异步任务 before_generate_reply_handle 确定要回复后,在生成回复前的处理 after_generate_reply_handle 确定要回复后,在生成回复后的处理 not_reply_handle 确定不回复后的处理 get_reply_probability 获取回复概率 bombing_buffer_message_handle 缓冲器炸飞消息后的处理 get_variable_parameters 暂不确定 set_variable_parameters 暂不确定 以下2个方法根据你的实现可以做调整: get_willing 获取某聊天流意愿 set_willing 设置某聊天流意愿 规范说明: 模块文件命名: `mode_{manager_type}.py` 示例: 若 `manager_type="aggressive"`,则模块文件应为 `mode_aggressive.py` 类命名: `{manager_type}WillingManager` (首字母大写) 示例: 在 `mode_aggressive.py` 中,类名应为 `AggressiveWillingManager` """ willing_config = LogConfig( # 使用消息发送专用样式 console_format=WILLING_STYLE_CONFIG["console_format"], file_format=WILLING_STYLE_CONFIG["file_format"], ) logger = get_module_logger("willing", config=willing_config) @dataclass class WillingInfo: """此类保存意愿模块常用的参数 Attributes: message (MessageRecv): 原始消息对象 chat (ChatStream): 聊天流对象 person_info_manager (PersonInfoManager): 用户信息管理对象 chat_id (str): 当前聊天流的标识符 person_id (str): 发送者的个人信息的标识符 group_id (str): 群组ID(如果是私聊则为空) is_mentioned_bot (bool): 是否提及了bot is_emoji (bool): 是否为表情包 interested_rate (float): 兴趣度 """ message: MessageRecv chat: ChatStream person_info_manager: PersonInfoManager chat_id: str person_id: str group_info: Optional[GroupInfo] is_mentioned_bot: bool is_emoji: bool interested_rate: float # current_mood: float 当前心情? class BaseWillingManager(ABC): """回复意愿管理基类""" @classmethod def create(cls, manager_type: str) -> "BaseWillingManager": try: module = importlib.import_module(f".mode_{manager_type}", __package__) manager_class = getattr(module, f"{manager_type.capitalize()}WillingManager") if not issubclass(manager_class, cls): raise TypeError(f"Manager class {manager_class.__name__} is not a subclass of {cls.__name__}") else: logger.info(f"成功载入willing模式:{manager_type}") return manager_class() except (ImportError, AttributeError, TypeError) as e: module = importlib.import_module(".mode_classical", __package__) manager_class = module.ClassicalWillingManager logger.info(f"载入当前意愿模式{manager_type}失败,使用经典配方~~~~") logger.debug(f"加载willing模式{manager_type}失败,原因: {str(e)}。") return manager_class() def __init__(self): self.chat_reply_willing: Dict[str, float] = {} # 存储每个聊天流的回复意愿(chat_id) self.ongoing_messages: Dict[str, WillingInfo] = {} # 当前正在进行的消息(message_id) self.lock = asyncio.Lock() self.global_config: BotConfig = global_config self.logger: LoguruLogger = logger def setup(self, message: MessageRecv, chat: ChatStream, is_mentioned_bot: bool, interested_rate: float): person_id = person_info_manager.get_person_id(chat.platform, chat.user_info.user_id) self.ongoing_messages[message.message_info.message_id] = WillingInfo( message=message, chat=chat, person_info_manager=person_info_manager, chat_id=chat.stream_id, person_id=person_id, group_info=chat.group_info, is_mentioned_bot=is_mentioned_bot, is_emoji=message.is_emoji, interested_rate=interested_rate, ) def delete(self, message_id: str): del_message = self.ongoing_messages.pop(message_id, None) if not del_message: logger.debug(f"删除异常,当前消息{message_id}不存在") @abstractmethod async def async_task_starter(self) -> None: """抽象方法:异步任务启动器""" pass @abstractmethod async def before_generate_reply_handle(self, message_id: str): """抽象方法:回复前处理""" pass @abstractmethod async def after_generate_reply_handle(self, message_id: str): """抽象方法:回复后处理""" pass @abstractmethod async def not_reply_handle(self, message_id: str): """抽象方法:不回复处理""" pass @abstractmethod async def get_reply_probability(self, message_id: str): """抽象方法:获取回复概率""" raise NotImplementedError @abstractmethod async def bombing_buffer_message_handle(self, message_id: str): """抽象方法:炸飞消息处理""" pass async def get_willing(self, chat_id: str): """获取指定聊天流的回复意愿""" async with self.lock: return self.chat_reply_willing.get(chat_id, 0) async def set_willing(self, chat_id: str, willing: float): """设置指定聊天流的回复意愿""" async with self.lock: self.chat_reply_willing[chat_id] = willing # @abstractmethod # async def get_variable_parameters(self) -> Dict[str, str]: # """抽象方法:获取可变参数""" # pass # @abstractmethod # async def set_variable_parameters(self, parameters: Dict[str, any]): # """抽象方法:设置可变参数""" # pass def init_willing_manager() -> BaseWillingManager: """ 根据配置初始化并返回对应的WillingManager实例 Returns: 对应mode的WillingManager实例 """ mode = global_config.willing_mode.lower() return BaseWillingManager.create(mode) # 全局willing_manager对象 willing_manager = init_willing_manager()