diff --git a/src/plugins/chat/__init__.py b/src/plugins/chat/__init__.py index ec3d4f01d..4833a0f5b 100644 --- a/src/plugins/chat/__init__.py +++ b/src/plugins/chat/__init__.py @@ -4,7 +4,7 @@ import os from loguru import logger from nonebot import get_driver, on_message, require -from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageSegment +from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageSegment,MessageEvent from nonebot.typing import T_State from ...common.database import Database @@ -50,8 +50,8 @@ emoji_manager.initialize() logger.debug(f"正在唤醒{global_config.BOT_NICKNAME}......") # 创建机器人实例 chat_bot = ChatBot() -# 注册群消息处理器 -group_msg = on_message(priority=5) +# 注册消息处理器 +msg_in = on_message(priority=5) # 创建定时任务 scheduler = require("nonebot_plugin_apscheduler").scheduler @@ -103,8 +103,8 @@ async def _(bot: Bot): asyncio.create_task(chat_manager._auto_save_task()) -@group_msg.handle() -async def _(bot: Bot, event: GroupMessageEvent, state: T_State): +@msg_in.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): await chat_bot.handle_message(event, bot) diff --git a/src/plugins/chat/bot.py b/src/plugins/chat/bot.py index 81361d81b..8359b9712 100644 --- a/src/plugins/chat/bot.py +++ b/src/plugins/chat/bot.py @@ -2,12 +2,17 @@ import re import time from random import random from loguru import logger -from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent +from nonebot.adapters.onebot.v11 import ( + Bot, + GroupMessageEvent, + MessageEvent, + PrivateMessageEvent, +) from ..memory_system.memory import hippocampus from ..moods.moods import MoodManager # 导入情绪管理器 from .config import global_config -from .cq_code import CQCode,cq_code_tool # 导入CQCode模块 +from .cq_code import CQCode, cq_code_tool # 导入CQCode模块 from .emoji_manager import emoji_manager # 导入表情包管理器 from .llm_generator import ResponseGenerator from .message import MessageSending, MessageRecv, MessageThinking, MessageSet @@ -24,6 +29,7 @@ from .utils_image import image_path_to_base64 from .willing_manager import willing_manager # 导入意愿管理器 from .message_base import UserInfo, GroupInfo, Seg + class ChatBot: def __init__(self): self.storage = MessageStorage() @@ -41,64 +47,91 @@ class ChatBot: if not self._started: self._started = True - async def handle_message(self, event: GroupMessageEvent, bot: Bot) -> None: - """处理收到的群消息""" + async def handle_message(self, event: MessageEvent, bot: Bot) -> None: + """处理收到的消息""" self.bot = bot # 更新 bot 实例 + if event.user_id in global_config.ban_user_id: + return + + # 处理私聊消息的逻辑 + if isinstance(event, PrivateMessageEvent): + if not 0 in global_config.talk_allowed_groups: + return + else: + user_info = UserInfo( + user_id=event.user_id, + user_nickname=( + await bot.get_stranger_info( + user_id=event.user_id, no_cache=True + ) + )["nickname"], + user_cardname=None, + platform="qq", + ) + logger.debug(user_info) + + # group_info = GroupInfo(group_id=0, group_name="私聊", platform="qq") + group_info = None + + else: + # 白名单设定由nontbot侧完成 + if event.group_id: + if event.group_id not in global_config.talk_allowed_groups: + return + + user_info = UserInfo( + user_id=event.user_id, + user_nickname=event.sender.nickname, + user_cardname=event.sender.card or None, + platform="qq", + ) + + group_info = GroupInfo( + group_id=event.group_id, group_name=None, platform="qq" + ) + # group_info = await bot.get_group_info(group_id=event.group_id) # sender_info = await bot.get_group_member_info(group_id=event.group_id, user_id=event.user_id, no_cache=True) - # 白名单设定由nontbot侧完成 - if event.group_id: - if event.group_id not in global_config.talk_allowed_groups: - return - if event.user_id in global_config.ban_user_id: - return - - user_info=UserInfo( - user_id=event.user_id, - user_nickname=event.sender.nickname, - user_cardname=event.sender.card or None, - platform='qq' - ) - - group_info=GroupInfo( - group_id=event.group_id, - group_name=None, - platform='qq' - ) - - message_cq=MessageRecvCQ( + message_cq = MessageRecvCQ( message_id=event.message_id, user_info=user_info, raw_message=str(event.original_message), group_info=group_info, reply_message=event.reply, - platform='qq' + platform="qq", ) - message_json=message_cq.to_dict() + message_json = message_cq.to_dict() # 进入maimbot - message=MessageRecv(message_json) - - groupinfo=message.message_info.group_info - userinfo=message.message_info.user_info - messageinfo=message.message_info + message = MessageRecv(message_json) + + groupinfo = message.message_info.group_info + userinfo = message.message_info.user_info + messageinfo = message.message_info # 消息过滤,涉及到config有待更新 - - chat = await chat_manager.get_or_create_stream(platform=messageinfo.platform, user_info=userinfo, group_info=groupinfo) + + chat = await chat_manager.get_or_create_stream( + platform=messageinfo.platform, user_info=userinfo, group_info=groupinfo + ) message.update_chat_stream(chat) - await relationship_manager.update_relationship(chat_stream=chat,) - await relationship_manager.update_relationship_value(chat_stream=chat, relationship_value = 0.5) + await relationship_manager.update_relationship( + chat_stream=chat, + ) + await relationship_manager.update_relationship_value( + chat_stream=chat, relationship_value=0.5 + ) await message.process() # 过滤词 for word in global_config.ban_words: if word in message.processed_plain_text: logger.info( - f"[{groupinfo.group_name}]{userinfo.user_nickname}:{message.processed_plain_text}") + f"[{groupinfo.group_name}]{userinfo.user_nickname}:{message.processed_plain_text}" + ) logger.info(f"[过滤词识别]消息中含有{word},filtered") return @@ -106,23 +139,25 @@ class ChatBot: for pattern in global_config.ban_msgs_regex: if re.search(pattern, message.raw_message): logger.info( - f"[{message.group_name}]{message.user_nickname}:{message.raw_message}") + f"[{message.group_name}]{message.user_nickname}:{message.raw_message}" + ) logger.info(f"[正则表达式过滤]消息匹配到{pattern},filtered") return - - current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(messageinfo.time)) - + current_time = time.strftime( + "%Y-%m-%d %H:%M:%S", time.localtime(messageinfo.time) + ) # topic=await topic_identifier.identify_topic_llm(message.processed_plain_text) - topic = '' + topic = "" interested_rate = 0 - interested_rate = await hippocampus.memory_activate_value(message.processed_plain_text) / 100 - logger.debug(f"对{message.processed_plain_text}" - f"的激活度:{interested_rate}") + interested_rate = ( + await hippocampus.memory_activate_value(message.processed_plain_text) / 100 + ) + logger.debug(f"对{message.processed_plain_text}" f"的激活度:{interested_rate}") # logger.info(f"\033[1;32m[主题识别]\033[0m 使用{global_config.topic_extract}主题: {topic}") - - await self.storage.store_message(message,chat, topic[0] if topic else None) + + await self.storage.store_message(message, chat, topic[0] if topic else None) is_mentioned = is_mentioned_bot_in_message(message) reply_probability = await willing_manager.change_reply_willing_received( @@ -131,38 +166,38 @@ class ChatBot: is_mentioned_bot=is_mentioned, config=global_config, is_emoji=message.is_emoji, - interested_rate=interested_rate + interested_rate=interested_rate, ) current_willing = willing_manager.get_willing(chat_stream=chat) - + logger.info( - f"[{current_time}][{chat.group_info.group_name}]{chat.user_info.user_nickname}:" + f"[{current_time}][{chat.group_info.group_name if chat.group_info.group_id else '私聊'}]{chat.user_info.user_nickname}:" f"{message.processed_plain_text}[回复意愿:{current_willing:.2f}][概率:{reply_probability * 100:.1f}%]" ) response = None - + if random() < reply_probability: - bot_user_info=UserInfo( + bot_user_info = UserInfo( user_id=global_config.BOT_QQ, user_nickname=global_config.BOT_NICKNAME, - platform=messageinfo.platform + platform=messageinfo.platform, ) tinking_time_point = round(time.time(), 2) - think_id = 'mt' + str(tinking_time_point) + think_id = "mt" + str(tinking_time_point) thinking_message = MessageThinking( message_id=think_id, chat_stream=chat, bot_user_info=bot_user_info, - reply=message + reply=message, ) - + message_manager.add_message(thinking_message) willing_manager.change_reply_willing_sent(chat) - - response,raw_content = await self.gpt.generate_response(message) - + + response, raw_content = await self.gpt.generate_response(message) + # print(f"response: {response}") if response: # print(f"有response: {response}") @@ -171,7 +206,10 @@ class ChatBot: # 找到message,删除 # print(f"开始找思考消息") for msg in container.messages: - if isinstance(msg, MessageThinking) and msg.message_info.message_id == think_id: + if ( + isinstance(msg, MessageThinking) + and msg.message_info.message_id == think_id + ): # print(f"找到思考消息: {msg}") thinking_message = msg container.messages.remove(msg) @@ -185,9 +223,9 @@ class ChatBot: # 记录开始思考的时间,避免从思考到回复的时间太久 thinking_start_time = thinking_message.thinking_start_time message_set = MessageSet(chat, think_id) - #计算打字时间,1是为了模拟打字,2是避免多条回复乱序 + # 计算打字时间,1是为了模拟打字,2是避免多条回复乱序 accu_typing_time = 0 - + mark_head = False for msg in response: # print(f"\033[1;32m[回复内容]\033[0m {msg}") @@ -196,16 +234,17 @@ class ChatBot: print(f"typing_time: {typing_time}") accu_typing_time += typing_time timepoint = tinking_time_point + accu_typing_time - message_segment = Seg(type='text', data=msg) + message_segment = Seg(type="text", data=msg) print(f"message_segment: {message_segment}") bot_message = MessageSending( message_id=think_id, chat_stream=chat, bot_user_info=bot_user_info, + sender_info=userinfo, message_segment=message_segment, reply=message, is_head=not mark_head, - is_emoji=False + is_emoji=False, ) print(f"bot_message: {bot_message}") if not mark_head: @@ -227,14 +266,14 @@ class ChatBot: if emoji_raw != None: emoji_path, description = emoji_raw - emoji_cq = image_path_to_base64(emoji_path) - + emoji_cq = image_path_to_base64(emoji_path) + if random() < 0.5: bot_response_time = tinking_time_point - 1 else: bot_response_time = bot_response_time + 1 - - message_segment = Seg(type='emoji', data=emoji_cq) + + message_segment = Seg(type="emoji", data=emoji_cq) bot_message = MessageSending( message_id=think_id, chat_stream=chat, @@ -242,25 +281,29 @@ class ChatBot: message_segment=message_segment, reply=message, is_head=False, - is_emoji=True + is_emoji=True, ) message_manager.add_message(bot_message) - + emotion = await self.gpt._get_emotion_tags(raw_content) logger.debug(f"为 '{response}' 获取到的情感标签为:{emotion}") valuedict = { - 'happy': 0.5, - 'angry': -1, - 'sad': -0.5, - 'surprised': 0.2, - 'disgusted': -1.5, - 'fearful': -0.7, - 'neutral': 0.1 + "happy": 0.5, + "angry": -1, + "sad": -0.5, + "surprised": 0.2, + "disgusted": -1.5, + "fearful": -0.7, + "neutral": 0.1, } - await relationship_manager.update_relationship_value(chat_stream=chat, relationship_value=valuedict[emotion[0]]) + await relationship_manager.update_relationship_value( + chat_stream=chat, relationship_value=valuedict[emotion[0]] + ) # 使用情绪管理器更新情绪 - self.mood_manager.update_mood_from_emotion(emotion[0], global_config.mood_intensity_factor) - + self.mood_manager.update_mood_from_emotion( + emotion[0], global_config.mood_intensity_factor + ) + # willing_manager.change_reply_willing_after_sent( # chat_stream=chat # ) diff --git a/src/plugins/chat/message.py b/src/plugins/chat/message.py index 5eb93d700..9301a20a4 100644 --- a/src/plugins/chat/message.py +++ b/src/plugins/chat/message.py @@ -280,6 +280,7 @@ class MessageSending(MessageProcessBase): message_id: str, chat_stream: ChatStream, bot_user_info: UserInfo, + sender_info:UserInfo, # 用来记录发送者信息,用于私聊回复 message_segment: Seg, reply: Optional['MessageRecv'] = None, is_head: bool = False, @@ -295,6 +296,7 @@ class MessageSending(MessageProcessBase): ) # 发送状态特有属性 + self.sender_info=sender_info self.reply_to_message_id = reply.message_info.message_id if reply else None self.is_head = is_head self.is_emoji = is_emoji diff --git a/src/plugins/chat/message_cq.py b/src/plugins/chat/message_cq.py index 6bfa47c3f..dc65b65ea 100644 --- a/src/plugins/chat/message_cq.py +++ b/src/plugins/chat/message_cq.py @@ -61,8 +61,12 @@ class MessageRecvCQ(MessageCQ): ): # 调用父类初始化 super().__init__(message_id, user_info, group_info, platform) + + # 私聊消息不携带group_info + if group_info is None: + pass - if group_info.group_name is None: + elif group_info.group_name is None: group_info.group_name = get_groupname(group_info.group_id) # 解析消息段 diff --git a/src/plugins/chat/message_sender.py b/src/plugins/chat/message_sender.py index 9db74633f..f987cf999 100644 --- a/src/plugins/chat/message_sender.py +++ b/src/plugins/chat/message_sender.py @@ -30,13 +30,14 @@ class Message_Sender: message: MessageSending, ) -> None: """发送消息""" + if isinstance(message, MessageSending): message_json = message.to_dict() message_send=MessageSendCQ( data=message_json ) - - if message_send.message_info.group_info: + # logger.debug(message_send.message_info,message_send.raw_message) + if message_send.message_info.group_info.group_id: try: await self._current_bot.send_group_msg( group_id=message.message_info.group_info.group_id, @@ -49,8 +50,9 @@ class Message_Sender: logger.error(f"[调试] 发送消息{message.processed_plain_text}失败") else: try: + logger.debug(message.message_info.user_info) await self._current_bot.send_private_msg( - user_id=message.message_info.user_info.user_id, + user_id=message.sender_info.user_id, message=message_send.raw_message, auto_escape=False )