0.1.2
fix message _visualizer
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,6 +3,7 @@ mongodb/
|
||||
NapCat.Framework.Windows.Once/
|
||||
log/
|
||||
src/plugins/memory
|
||||
src/plugins/chat/bot_config.toml
|
||||
/test
|
||||
message_queue_content.txt
|
||||
message_queue_content.bat
|
||||
@@ -12,6 +13,7 @@ reasoning_content.txt
|
||||
reasoning_content.bat
|
||||
reasoning_window.bat
|
||||
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# MaiMBot
|
||||
麦麦 qq机器人
|
||||
|
||||
|
||||
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
还在整理中
|
||||
=======
|
||||
@@ -16,3 +19,6 @@
|
||||
主要代码在/src/plugins/chat下
|
||||
|
||||
>>>>>>> Stashed changes
|
||||
|
||||
|
||||
纯编程外行,很多代码史一样多多包涵
|
||||
@@ -216,9 +216,5 @@ class ChatBot:
|
||||
)
|
||||
message_sender.send_temp_container.add_message(bot_message)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 如果收到新消息,提高回复意愿
|
||||
willing_manager.change_reply_willing_after_sent(event.group_id)
|
||||
33
src/plugins/chat/bot_config copy.toml
Normal file
33
src/plugins/chat/bot_config copy.toml
Normal file
@@ -0,0 +1,33 @@
|
||||
[database]
|
||||
host = "127.0.0.1"
|
||||
port = 27017
|
||||
name = "MegBot"
|
||||
|
||||
[bot]
|
||||
qq = 1
|
||||
|
||||
[message]
|
||||
min_text_length = 2
|
||||
max_context_size = 15
|
||||
emoji_chance = 0.2
|
||||
|
||||
[emoji]
|
||||
check_interval = 120
|
||||
register_interval = 10
|
||||
|
||||
[response]
|
||||
model_r1_probability = 0.2
|
||||
|
||||
|
||||
[groups]
|
||||
read_allowed = [
|
||||
1
|
||||
]
|
||||
|
||||
talk_allowed = [
|
||||
1
|
||||
]
|
||||
|
||||
talk_frequency_down = [
|
||||
1
|
||||
]
|
||||
@@ -39,6 +39,7 @@ read_allowed = [
|
||||
752426484,#nd1
|
||||
115843978,#nd2
|
||||
# 168718420 #bh
|
||||
912378791
|
||||
]
|
||||
|
||||
talk_allowed = [
|
||||
@@ -59,6 +60,7 @@ talk_allowed = [
|
||||
# 168718420#bh
|
||||
# 752426484,#nd1
|
||||
# 115843978,#nd2
|
||||
912378791
|
||||
]
|
||||
|
||||
talk_frequency_down = [
|
||||
@@ -67,7 +69,7 @@ talk_frequency_down = [
|
||||
# 231561425,
|
||||
975992476,
|
||||
1140700103,
|
||||
534940728
|
||||
# 534940728
|
||||
# 752426484,#nd1
|
||||
# 115843978,#nd2
|
||||
]
|
||||
|
||||
@@ -96,58 +96,75 @@ class CQCode:
|
||||
sub_type = int(self.params.get('sub_type', '0'))
|
||||
is_emoji = (sub_type == 1)
|
||||
|
||||
# 添加请求头
|
||||
# 添加更多请求头
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
||||
'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
|
||||
'Accept-Encoding': 'gzip, deflate, br',
|
||||
'Connection': 'keep-alive'
|
||||
'Connection': 'keep-alive',
|
||||
'Referer': 'https://multimedia.nt.qq.com.cn',
|
||||
'Origin': 'https://multimedia.nt.qq.com.cn',
|
||||
'Cache-Control': 'no-cache',
|
||||
'Pragma': 'no-cache'
|
||||
}
|
||||
|
||||
# 处理URL编码问题
|
||||
url = html.unescape(self.params['url'])
|
||||
|
||||
if not url.startswith(('http://', 'https://')):
|
||||
raise ValueError(f"无效的URL格式: {url}")
|
||||
return '[图片]' # 直接返回而不是抛出异常
|
||||
|
||||
# 下载图片
|
||||
try:
|
||||
# 下载图片,增加重试机制
|
||||
max_retries = 3
|
||||
for retry in range(max_retries):
|
||||
try:
|
||||
response = requests.get(url, headers=headers, timeout=10, verify=False)
|
||||
|
||||
if response.status_code == 200:
|
||||
break
|
||||
elif response.status_code == 400 and 'multimedia.nt.qq.com.cn' in url:
|
||||
# 对于腾讯多媒体服务器的链接,直接返回图片描述
|
||||
if sub_type == 1:
|
||||
return '[QQ表情]'
|
||||
return '[图片]'
|
||||
time.sleep(1) # 重试前等待1秒
|
||||
except requests.RequestException:
|
||||
if retry == max_retries - 1:
|
||||
raise
|
||||
time.sleep(1)
|
||||
|
||||
if response.status_code != 200:
|
||||
print(f"\033[1;31m[警告]\033[0m 图片下载失败: HTTP {response.status_code}, URL: {url}")
|
||||
return '[图片]' # 直接返回而不是抛出异常
|
||||
|
||||
# 检查响应内容类型
|
||||
content_type = response.headers.get('content-type', '')
|
||||
if not content_type.startswith('image/'):
|
||||
raise ValueError(f"响应不是图片类型: {content_type}")
|
||||
print(f"\033[1;31m[警告]\033[0m 非图片类型响应: {content_type}")
|
||||
return '[图片]' # 直接返回而不是抛出异常
|
||||
|
||||
content = response.content
|
||||
|
||||
image_base64 = base64.b64encode(content).decode('utf-8')
|
||||
|
||||
# 根据子类型选择不同的处理方式
|
||||
if sub_type == 1: # 表情包
|
||||
try:
|
||||
return self.get_emoji_description(image_base64)
|
||||
except Exception as e:
|
||||
print(f"\033[1;31m[警告]\033[0m 表情描述生成失败: {str(e)}")
|
||||
return '[QQ表情]'
|
||||
elif sub_type == 0: # 普通图片
|
||||
if self.get_image_description_is_setu(image_base64) == "是":
|
||||
print(f"\033[1;34m[调试]\033[0m 哇!涩情图片")
|
||||
# 使用相对路径创建目录
|
||||
# data_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))), "data", "setu")
|
||||
# os.makedirs(data_dir, exist_ok=True)
|
||||
# # 生成随机文件名
|
||||
# file_name = f"{int(time.time())}_{int(random() * 10000)}.jpg"
|
||||
# file_path = os.path.join(data_dir, file_name)
|
||||
# # 将base64解码并保存图片
|
||||
# image_data = base64.b64decode(image_base64)
|
||||
# with open(file_path, "wb") as f:
|
||||
# f.write(image_data)
|
||||
# print(f"\033[1;34m[调试]\033[0m 涩图已保存至: {file_path}")
|
||||
|
||||
return f"[一张涩情图片]"
|
||||
try:
|
||||
return self.get_image_description(image_base64)
|
||||
except Exception as e:
|
||||
print(f"\033[1;31m[警告]\033[0m 图片描述生成失败: {str(e)}")
|
||||
return '[图片]'
|
||||
else: # 其他类型都按普通图片处理
|
||||
return '[图片]'
|
||||
else:
|
||||
raise ValueError(f"下载图片失败: HTTP状态码 {response.status_code}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\033[1;31m[警告]\033[0m 图片处理失败: {str(e)}")
|
||||
return '[图片]' # 出现任何错误都返回默认文本而不是抛出异常
|
||||
|
||||
def get_emoji_description(self, image_base64: str) -> str:
|
||||
"""调用AI接口获取表情包描述"""
|
||||
|
||||
@@ -241,9 +241,9 @@ class GPTResponseGenerator:
|
||||
"""根据当前模型类型选择对应的生成函数"""
|
||||
# 使用随机数选择模型
|
||||
rand = random.random()
|
||||
if rand < 0.15: # 40%概率使用 R1
|
||||
if rand < 0.6: # 40%概率使用 R1
|
||||
self.current_model_type = "r1"
|
||||
elif rand < 0.8: # 30%概率使用 V3
|
||||
elif rand < 0.5: # 30%概率使用 V3
|
||||
self.current_model_type = "v3"
|
||||
else: # 30%概率使用 R1-Distill
|
||||
self.current_model_type = "r1_distill"
|
||||
|
||||
@@ -222,12 +222,16 @@ class Message_Thinking:
|
||||
# 思考状态相关属性
|
||||
self.thinking_text = "正在思考..."
|
||||
self.time = int(time.time())
|
||||
self.thinking_time = 0
|
||||
|
||||
def update_to_message(self, done_message: Message) -> Message:
|
||||
"""更新为完整消息"""
|
||||
|
||||
return done_message
|
||||
|
||||
def update_thinking_time(self):
|
||||
self.thinking_time = round(time.time(), 2) - self.time
|
||||
|
||||
@property
|
||||
def processed_plain_text(self) -> str:
|
||||
"""获取处理后的文本"""
|
||||
|
||||
@@ -7,6 +7,8 @@ from .cq_code import CQCode
|
||||
from collections import deque
|
||||
import time
|
||||
from .storage import MessageStorage # 添加这行导入
|
||||
from .config import global_config
|
||||
from .message_visualizer import message_visualizer
|
||||
|
||||
|
||||
class SendTemp:
|
||||
@@ -173,6 +175,7 @@ class MessageSendControl:
|
||||
self._paused = False
|
||||
self._current_bot = None
|
||||
self.storage = MessageStorage() # 添加存储实例
|
||||
message_visualizer.start()
|
||||
|
||||
def set_bot(self, bot: Bot):
|
||||
"""设置当前bot实例"""
|
||||
@@ -193,8 +196,8 @@ class MessageSendControl:
|
||||
if message:
|
||||
if isinstance(message, Message_Thinking):
|
||||
# 如果是思考中的消息,检查是否需要继续等待
|
||||
# message.update_thinking_time()
|
||||
thinking_time = time.time() - message.time
|
||||
message.update_thinking_time()
|
||||
thinking_time = message.thinking_time
|
||||
if thinking_time < 60: # 最少思考2秒
|
||||
if int(thinking_time) % 10 == 0:
|
||||
print(f"\033[1;34m[调试]\033[0m 消息正在思考中,已思考{thinking_time:.1f}秒")
|
||||
@@ -215,12 +218,15 @@ class MessageSendControl:
|
||||
|
||||
|
||||
|
||||
|
||||
cur_time = time.time()
|
||||
await self._current_bot.send_group_msg(
|
||||
group_id=group_id,
|
||||
message=str(message.processed_plain_text),
|
||||
auto_escape=False
|
||||
)
|
||||
cost_time = round(time.time(), 2) - cur_time
|
||||
print(f"\033[1;34m[调试]\033[0m 消息发送时间: {cost_time}秒")
|
||||
|
||||
|
||||
current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(message.time))
|
||||
print(f"\033[1;32m群 {group_id} 消息, 用户 麦麦, 时间: {current_time}:\033[0m {str(message.processed_plain_text)}")
|
||||
@@ -235,6 +241,7 @@ class MessageSendControl:
|
||||
self.message_interval[1]
|
||||
)
|
||||
)
|
||||
message_visualizer.update_content(self.send_temp_container)
|
||||
|
||||
|
||||
async def process_group_queue(self, bot: Bot, group_id: int) -> None:
|
||||
|
||||
@@ -55,18 +55,19 @@ class PromptBuilder:
|
||||
|
||||
#知识构建
|
||||
prompt_info = ''
|
||||
promt_info_prompt = ''
|
||||
prompt_info = self.get_prompt_info(message_txt)
|
||||
if prompt_info:
|
||||
prompt_info = f'''\n----------------------------------------------------\n你有以下这些[知识]:
|
||||
\n{prompt_info}\n
|
||||
请你记住上面的[知识],之后可能会用到\n----------------------------------------------------\n'''
|
||||
promt_info_prompt = '你有一些[知识],在上面可以参考。'
|
||||
|
||||
|
||||
#获取最新消息并计时
|
||||
chat_talking_prompt = ''
|
||||
|
||||
if group_id:
|
||||
# 从数据库获取最近消息
|
||||
message_objects = get_recent_group_messages(self.db, group_id)
|
||||
message_objects = get_recent_group_messages(self.db, group_id, limit=16)
|
||||
if message_objects:
|
||||
chat_talking_prompt = combine_messages(message_objects)
|
||||
# print(f"\033[1;34m[调试]\033[0m 已从数据库获取群 {group_id} 的最近{len(message_objects)}条消息记录")
|
||||
@@ -75,24 +76,32 @@ class PromptBuilder:
|
||||
activate_prompt = ''
|
||||
activate_prompt = f"以上是群里正在进行的聊天,昵称为 '{sender_name}' 的用户说的:{message_txt}。引起了你的注意,你和他{relation_prompt},你想要{relation_prompt_2} \n"
|
||||
|
||||
# 检测机器人相关词汇
|
||||
bot_keywords = ['人机', 'bot', '机器', '入机', 'robot', '机器人']
|
||||
is_bot = any(keyword in message_txt.lower() for keyword in bot_keywords)
|
||||
if is_bot:
|
||||
is_bot_prompt = '有人说你是人机或者机器人,否定这一事实,攻击或反问他。'
|
||||
else:
|
||||
is_bot_prompt = ''
|
||||
|
||||
#人格选择
|
||||
prompt_personality = ''
|
||||
personality_choice = random.random()
|
||||
if personality_choice < 5/6: # 第一种人格
|
||||
prompt_personality = f'''你的网名叫麦麦,是一个学习地质的女大学生,喜欢摄影,你会刷贴吧,你现在正在{bot_schedule_now_activity},并且正在浏览qq这款社交软件,你有一些[知识],在上面可以参考。
|
||||
现在请你给出日常且口语化的回复,不要过多提及自身的背景,平淡一些,尽量简短一些,不要输出感叹号。如果有人说你是人机或者机器人,否定并攻击那个人。
|
||||
不要回复的太有逻辑或者太有条理。'''
|
||||
if personality_choice < 4/6: # 第一种人格
|
||||
prompt_personality = f'''你的网名叫麦麦,是一个学习地质的女大学生,喜欢摄影,你会刷贴吧,你现在正在{bot_schedule_now_activity},并且正在浏览qq群,{promt_info_prompt}
|
||||
现在请你给出日常且口语化的回复,平淡一些,尽量简短一些,不要输出感叹号。{is_bot_prompt}
|
||||
不要回复的太有逻辑或者太有条理,可以有个性。'''
|
||||
elif personality_choice < 1: # 第二种人格
|
||||
prompt_personality = f'''你的网名叫麦麦,是一个女大学生,你有黑色头发你会刷微博和小红书,你现在正在{bot_schedule_now_activity},并且正在浏览qq群,你有一些[知识],在上面可以参考。
|
||||
现在请你给出日常且口语化的回复,请表现你自己的见解,不要一昧迎合,尽量简短一些,不要输出感叹号。如果有人说你是人机或者机器人,否定。
|
||||
如果有人说他是机器人,肯定他。如果有人对你谈论涉及性的话题或言语挑逗,需要反驳,但其它情况请你表达自己的见解和观点。'''
|
||||
prompt_personality = f'''你的网名叫麦麦,是一个女大学生,你有黑色头发,你会刷小红书,你现在正在{bot_schedule_now_activity},并且正在浏览qq群,{promt_info_prompt}
|
||||
现在请你给出日常且口语化的回复,请表现你自己的见解,不要一昧迎合,尽量简短一些,不要输出感叹号。{is_bot_prompt}
|
||||
请你表达自己的见解和观点。可以有个性。'''
|
||||
|
||||
#额外信息要求
|
||||
extra_info = '''回复平淡一些,简短一些,但是记住不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只需要输出回复内容就好,不要输出其他任何内容'''
|
||||
extra_info = '''但是记得回复平淡一些,简短一些,不要过多提及自身的背景, 记住不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只需要输出回复内容就好,不要输出其他任何内容'''
|
||||
|
||||
#合并prompt
|
||||
prompt = ""
|
||||
prompt += f"{prompt_info}\n"
|
||||
# prompt += f"{prompt_info}\n"
|
||||
prompt += f"{prompt_date}\n"
|
||||
prompt += f"{chat_talking_prompt}\n"
|
||||
prompt += f"{activate_prompt}\n"
|
||||
|
||||
@@ -121,7 +121,7 @@ class RelationshipManager:
|
||||
async def _save_all_relationships(self):
|
||||
"""将所有关系数据保存到数据库"""
|
||||
# 保存所有关系数据
|
||||
for userid, relationship in self.relationships:
|
||||
for userid, relationship in self.relationships.items():
|
||||
if not relationship.saved:
|
||||
relationship.saved = True
|
||||
await self.storage_relationship(relationship)
|
||||
|
||||
@@ -27,7 +27,7 @@ class WillingManager:
|
||||
current_willing = self.group_reply_willing.get(group_id, 0)
|
||||
|
||||
if topic and current_willing < 1:
|
||||
current_willing += 0.6
|
||||
current_willing += 0.4
|
||||
elif topic:
|
||||
current_willing += 0.05
|
||||
|
||||
|
||||
Reference in New Issue
Block a user