diff --git a/README.md b/README.md
index c437c12ec..565ae59a3 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@

-
+

@@ -15,7 +15,8 @@
基于napcat、nonebot和mongodb的专注于群聊天的qqbot
-> ⚠️ **警告**:代码可能随时更改,目前版本不一定是稳定版本,请自行了解qqbot的风险
+> ⚠️ **警告**:代码可能随时更改,目前版本不一定是稳定版本,并请自行了解qqbot的风险
+> ⚠️ **警告**:由于麦麦一直在迭代,所以可能存在一些bug,请自行测试,包括胡言乱语(
## 🚀 快速开始
@@ -44,7 +45,7 @@
## 🎯 功能介绍
### 💬 聊天功能
-- 支持关键词检索主动发言:对消息的话题topic进行识别,如果检测到麦麦存储过的话题就会主动进行发言,没写完
+- 支持关键词检索主动发言:对消息的话题topic进行识别,如果检测到麦麦存储过的话题就会主动进行发言,目前有bug
- 支持bot名字呼唤发言:检测到"麦麦"会主动发言,可配置
- 使用硅基流动的api进行回复生成,可随机使用R1,V3,R1-distill等模型,未来将加入官网api支持
- 动态的prompt构建器,更拟人
@@ -53,7 +54,7 @@
### 😊 表情包功能
- 支持根据发言内容发送对应情绪的表情包:未完善,可以用
-- 会自动偷群友的表情包(未完善,暂时禁用)
+- 会自动偷群友的表情包(未完善,暂时禁用)目前有bug
### 📅 日程功能
- 麦麦会自动生成一天的日程,实现更拟人的回复
@@ -64,11 +65,9 @@
### 📚 知识库功能
- 基于embedding模型的知识库,手动放入txt会自动识别,写完了,暂时禁用
-### 📊 可视化的界面
-- 基于gradio的后台界面,可以显示实时消息,思考过程和消息发送流(WIP)
-
### 👥 关系功能
- 针对每个用户创建"关系",可以对不同用户进行个性化回复,目前只有极其简单的好感度(WIP)
+- 针对每个群创建"群印象",可以对不同群进行个性化回复(WIP)
## 🚧 开发中功能
- 人格功能:WIP
diff --git a/src/plugins/chat/bot.py b/src/plugins/chat/bot.py
index 09fc3aa08..489bd14e4 100644
--- a/src/plugins/chat/bot.py
+++ b/src/plugins/chat/bot.py
@@ -6,7 +6,6 @@ from .llm_generator import LLMResponseGenerator
from .message_stream import MessageStream, MessageStreamContainer
from .topic_identifier import topic_identifier
from random import random
-from .group_info_manager import GroupInfoManager # 导入群信息管理器
from .emoji_manager import emoji_manager # 导入表情包管理器
import time
import os
@@ -15,14 +14,13 @@ from .message_send_control import message_sender # 导入消息发送控制器
from .message import Message_Thinking # 导入 Message_Thinking 类
from .relationship_manager import relationship_manager
from .willing_manager import willing_manager # 导入意愿管理器
-
+from .utils import is_mentioned_bot_in_txt, calculate_typing_time
class ChatBot:
def __init__(self, config: BotConfig):
self.config = config
self.storage = MessageStorage()
self.gpt = LLMResponseGenerator(config)
- self.group_info_manager = GroupInfoManager() # 初始化群信息管理器
self.bot = None # bot 实例引用
self._started = False
@@ -79,26 +77,19 @@ class ChatBot:
# print(f"- original_message: {event.reply.original_message}")
'''
- # 获取群组信息,发送消息的用户信息,并对数据库内容做一次更新
group_info = await bot.get_group_info(group_id=event.group_id)
- await self.group_info_manager.update_group_info(
- group_id=event.group_id,
- group_name=group_info['group_name'],
- member_count=group_info['member_count']
- )
+
sender_info = await bot.get_group_member_info(group_id=event.group_id, user_id=event.user_id, no_cache=True)
- # print(f"\033[1;32m[关系管理]\033[0m 更新关系: {sender_info}")
-
+
await relationship_manager.update_relationship(user_id = event.user_id, data = sender_info)
await relationship_manager.update_relationship_value(user_id = event.user_id, relationship_value = 0.5)
print(f"\033[1;32m[关系管理]\033[0m 更新关系值: {relationship_manager.get_relationship(event.user_id).relationship_value}")
-
message = Message(
group_id=event.group_id,
user_id=event.user_id,
@@ -113,13 +104,12 @@ class ChatBot:
topic = topic_identifier.identify_topic_jieba(message.processed_plain_text)
print(f"\033[1;32m[主题识别]\033[0m 主题: {topic}")
+
await self.storage.store_message(message, topic[0] if topic else None)
- current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(message.time))
+
- print(f"\033[1;34m[调试]\033[0m 当前消息是否是表情包: {message.is_emoji}")
-
- is_mentioned = self.is_mentioned_bot(message)
+ is_mentioned = is_mentioned_bot_in_txt(message.processed_plain_text)
reply_probability = willing_manager.change_reply_willing_received(
event.group_id,
topic[0] if topic else None,
@@ -133,60 +123,47 @@ class ChatBot:
print(f"\033[1;32m[{current_time}][{message.group_name}]{message.user_nickname}:\033[0m {message.processed_plain_text}\033[1;36m[回复意愿:{current_willing:.2f}][概率:{reply_probability:.1f}]\033[0m")
response = ""
+ # 创建思考消息
if random() < reply_probability:
tinking_time_point = round(time.time(), 2)
think_id = 'mt' + str(tinking_time_point)
-
thinking_message = Message_Thinking(message=message,message_id=think_id)
-
message_sender.send_temp_container.add_message(thinking_message)
willing_manager.change_reply_willing_sent(thinking_message.group_id)
- # 生成回复
+
response, emotion = await self.gpt.generate_response(message)
# 如果生成了回复,发送并记录
+
+
if response:
message_set = MessageSet(event.group_id, self.config.BOT_QQ, think_id)
- if isinstance(response, list):
- # 将多条消息合并成一条
- for msg in response:
- # print(f"\033[1;34m[调试]\033[0m 载入消息消息: {msg}")
- # bot_response_time = round(time.time(), 2)
- timepoint = tinking_time_point-0.3
- bot_message = Message(
- group_id=event.group_id,
- user_id=self.config.BOT_QQ,
- message_id=think_id,
- message_based_id=event.message_id,
- raw_message=msg,
- plain_text=msg,
- processed_plain_text=msg,
- user_nickname="麦麦",
- group_name=message.group_name,
- time=timepoint
- )
- # print(f"\033[1;34m[调试]\033[0m 添加消息到消息组: {bot_message}")
- message_set.add_message(bot_message)
- # print(f"\033[1;34m[调试]\033[0m 输入消息组: {message_set}")
- message_sender.send_temp_container.update_thinking_message(message_set)
- else:
- # bot_response_time = round(time.time(), 2)
+ accu_typing_time = 0
+ for msg in response:
+ print(f"当前消息: {msg}")
+ typing_time = calculate_typing_time(msg)
+ accu_typing_time += typing_time
+ timepoint = tinking_time_point+accu_typing_time
+ # print(f"\033[1;32m[调试]\033[0m 消息: {msg},添加!, 累计打字时间: {accu_typing_time:.2f}秒")
+
bot_message = Message(
group_id=event.group_id,
user_id=self.config.BOT_QQ,
message_id=think_id,
message_based_id=event.message_id,
- raw_message=response,
- plain_text=response,
- processed_plain_text=response,
+ raw_message=msg,
+ plain_text=msg,
+ processed_plain_text=msg,
user_nickname="麦麦",
group_name=message.group_name,
- time=tinking_time_point
+ time=timepoint
)
- # print(f"\033[1;34m[调试]\033[0m 更新单条消息: {bot_message}")
- message_sender.send_temp_container.update_thinking_message(bot_message)
+ message_set.add_message(bot_message)
+
+ message_sender.send_temp_container.update_thinking_message(message_set)
+
bot_response_time = tinking_time_point
@@ -197,8 +174,8 @@ class ChatBot:
if random() < 0.5:
bot_response_time = tinking_time_point - 1
- # else:
- # bot_response_time = bot_response_time + 1
+ else:
+ bot_response_time = bot_response_time + 1
bot_message = Message(
group_id=event.group_id,
diff --git a/src/plugins/chat/bot_config_toml b/src/plugins/chat/bot_config_toml
index 1cef503af..5b9010035 100644
--- a/src/plugins/chat/bot_config_toml
+++ b/src/plugins/chat/bot_config_toml
@@ -5,6 +5,7 @@ name = "MegBot"
[bot]
qq = #填入你的机器人QQ
+nickname = "麦麦"
[message]
min_text_length = 2
@@ -16,7 +17,9 @@ check_interval = 120
register_interval = 10
[response]
-model_r1_probability = 0.2 #使用R1回复的概率(没启用)
+model_r1_probability = 0.8
+model_v3_probability = 0.1
+model_r1_distill_probability = 0.1
[groups]
diff --git a/src/plugins/chat/config.py b/src/plugins/chat/config.py
index 44e14827d..d44be7bd0 100644
--- a/src/plugins/chat/config.py
+++ b/src/plugins/chat/config.py
@@ -26,6 +26,7 @@ class BotConfig:
DATABASE_NAME: str = "MegBot"
BOT_QQ: Optional[int] = None
+ BOT_NICKNAME: Optional[str] = None
# 消息处理相关配置
MIN_TEXT_LENGTH: int = 2 # 最小处理文本长度
@@ -39,7 +40,9 @@ class BotConfig:
EMOJI_CHECK_INTERVAL: int = 120 # 表情包检查间隔(分钟)
EMOJI_REGISTER_INTERVAL: int = 10 # 表情包注册间隔(分钟)
- MODEL_R1_PROBABILITY: float = 0.3 # R1模型概率
+ MODEL_R1_PROBABILITY: float = 0.8 # R1模型概率
+ MODEL_V3_PROBABILITY: float = 0.1 # V3模型概率
+ MODEL_R1_DISTILL_PROBABILITY: float = 0.1 # R1蒸馏模型概率
@classmethod
def load_config(cls, config_path: str = "bot_config.toml") -> "BotConfig":
@@ -66,11 +69,13 @@ class BotConfig:
bot_config = toml_dict["bot"]
bot_qq = bot_config.get("qq")
config.BOT_QQ = int(bot_qq)
-
+ config.BOT_NICKNAME = bot_config.get("nickname", config.BOT_NICKNAME)
if "response" in toml_dict:
response_config = toml_dict["response"]
config.MODEL_R1_PROBABILITY = response_config.get("model_r1_probability", config.MODEL_R1_PROBABILITY)
+ config.MODEL_V3_PROBABILITY = response_config.get("model_v3_probability", config.MODEL_V3_PROBABILITY)
+ config.MODEL_R1_DISTILL_PROBABILITY = response_config.get("model_r1_distill_probability", config.MODEL_R1_DISTILL_PROBABILITY)
# 消息配置
if "message" in toml_dict:
diff --git a/src/plugins/chat/group_info_manager.py b/src/plugins/chat/group_info_manager.py
deleted file mode 100644
index 52cf06138..000000000
--- a/src/plugins/chat/group_info_manager.py
+++ /dev/null
@@ -1,107 +0,0 @@
-from typing import Dict, Optional
-from ...common.database import Database
-import time
-
-class GroupInfoManager:
- def __init__(self):
- self.db = Database.get_instance()
- # 确保必要的集合存在
- self._ensure_collections()
-
- def _ensure_collections(self):
- """确保数据库中有必要的集合"""
- collections = self.db.db.list_collection_names()
- if 'group_info' not in collections:
- self.db.db.create_collection('group_info')
- if 'user_info' not in collections:
- self.db.db.create_collection('user_info')
-
- async def update_group_info(self, group_id: int, group_name: str, group_notice: str = "",
- member_count: int = 0, admins: list = None):
- """更新群组信息"""
- try:
- group_data = {
- "group_id": group_id,
- "group_name": group_name,
- "group_notice": group_notice,
- "member_count": member_count,
- "admins": admins or [],
- "last_updated": time.time()
- }
-
- # 使用 upsert 来更新或插入数据
- self.db.db.group_info.update_one(
- {"group_id": group_id},
- {"$set": group_data},
- upsert=True
- )
- except Exception as e:
- print(f"\033[1;31m[错误]\033[0m 更新群信息失败: {str(e)}")
-
- async def update_user_info(self, user_id: int, nickname: str, group_id: int = None,
- group_card: str = None, age: int = None, gender: str = None,
- location: str = None):
- """更新用户信息"""
- try:
- # 基础用户数据
- user_data = {
- "user_id": user_id,
- "nickname": nickname,
- "last_updated": time.time()
- }
-
- # 添加可选字段
- if age is not None:
- user_data["age"] = age
- if gender is not None:
- user_data["gender"] = gender
- if location is not None:
- user_data["location"] = location
-
- # 如果提供了群相关信息,更新用户在该群的信息
- if group_id is not None:
- group_info_key = f"group_info.{group_id}"
- group_data = {
- group_info_key: {
- "group_card": group_card,
- "last_active": time.time()
- }
- }
- user_data.update(group_data)
-
- # 使用 upsert 来更新或插入数据
- result = self.db.db.user_info.update_one(
- {"user_id": user_id},
- {
- "$set": user_data,
- "$addToSet": {"groups": group_id} if group_id else {}
- },
- upsert=True
- )
-
- # print(f"\033[1;32m[用户信息]\033[0m 更新用户 {nickname}({user_id}) 的信息 {'成功' if result.modified_count > 0 or result.upserted_id else '未变化'}")
-
- except Exception as e:
- print(f"\033[1;31m[错误]\033[0m 更新用户信息失败: {str(e)}")
- print(f"用户ID: {user_id}, 昵称: {nickname}, 群ID: {group_id}, 群名片: {group_card}")
-
- async def get_group_info(self, group_id: int) -> Optional[Dict]:
- """获取群组信息"""
- try:
- return self.db.db.group_info.find_one({"group_id": group_id})
- except Exception as e:
- print(f"\033[1;31m[错误]\033[0m 获取群信息失败: {str(e)}")
- return None
-
- async def get_user_info(self, user_id: int, group_id: int = None) -> Optional[Dict]:
- """获取用户信息"""
- try:
- user_info = self.db.db.user_info.find_one({"user_id": user_id})
- if user_info and group_id:
- # 添加该用户在特定群的信息
- group_info_key = f"group_info.{group_id}"
- user_info["current_group_info"] = user_info.get(group_info_key, {})
- return user_info
- except Exception as e:
- print(f"\033[1;31m[错误]\033[0m 获取用户信息失败: {str(e)}")
- return None
\ No newline at end of file
diff --git a/src/plugins/chat/llm_generator.py b/src/plugins/chat/llm_generator.py
index dece848b2..176996c93 100644
--- a/src/plugins/chat/llm_generator.py
+++ b/src/plugins/chat/llm_generator.py
@@ -14,8 +14,8 @@ from dotenv import load_dotenv
from .relationship_manager import relationship_manager
from ..schedule.schedule_generator import bot_schedule
from .prompt_builder import prompt_builder
-from .config import llm_config
-from .utils import get_embedding, split_into_sentences, process_text_with_typos
+from .config import llm_config, global_config
+from .utils import process_llm_response
# 获取当前文件的绝对路径
@@ -38,15 +38,20 @@ class LLMResponseGenerator:
async def generate_response(self, message: Message) -> Optional[Union[str, List[str]]]:
"""根据当前模型类型选择对应的生成函数"""
- # 使用随机数选择模型
+ # 从global_config中获取模型概率值
+ model_r1_probability = global_config.MODEL_R1_PROBABILITY
+ model_v3_probability = global_config.MODEL_V3_PROBABILITY
+ model_r1_distill_probability = global_config.MODEL_R1_DISTILL_PROBABILITY
+
+ # 生成随机数并根据概率选择模型
rand = random.random()
- if rand < 0.8: # 60%概率使用 R1
- self.current_model_type = "r1"
- elif rand < 0.5: # 20%概率使用 V3
- self.current_model_type = "v3"
- else: # 20%概率使用 R1-Distill
- self.current_model_type = "r1_distill"
-
+ if rand < model_r1_probability:
+ self.current_model_type = 'r1'
+ elif rand < model_r1_probability + model_v3_probability:
+ self.current_model_type = 'v3'
+ else:
+ self.current_model_type = 'r1_distill' # 默认使用 R1-Distill
+
print(f"+++++++++++++++++麦麦{self.current_model_type}思考中+++++++++++++++++")
if self.current_model_type == 'r1':
model_response = await self._generate_r1_response(message)
@@ -64,18 +69,22 @@ class LLMResponseGenerator:
return model_response, emotion
- async def _generate_r1_response(self, message: Message) -> Optional[str]:
- """使用 DeepSeek-R1 模型生成回复"""
- # 获取群聊上下文
- group_chat = await self._get_group_chat_context(message)
+ async def _generate_base_response(
+ self,
+ message: Message,
+ model_name: str,
+ model_params: Optional[Dict[str, Any]] = None
+ ) -> Optional[str]:
sender_name = message.user_nickname or f"用户{message.user_id}"
+
+ # 获取关系值
if relationship_manager.get_relationship(message.user_id):
relationship_value = relationship_manager.get_relationship(message.user_id).relationship_value
print(f"\033[1;32m[关系管理]\033[0m 回复中_当前关系值: {relationship_value}")
else:
relationship_value = 0.0
-
- # 构建 prompt
+
+ # 构建prompt
prompt = prompt_builder._build_prompt(
message_txt=message.processed_plain_text,
sender_name=sender_name,
@@ -83,142 +92,75 @@ class LLMResponseGenerator:
group_id=message.group_id
)
+ # 设置默认参数
+ default_params = {
+ "model": model_name,
+ "messages": [{"role": "user", "content": prompt}],
+ "stream": False,
+ "max_tokens": 1024,
+ "temperature": 0.7
+ }
+
+ # 更新参数
+ if model_params:
+ default_params.update(model_params)
+
def create_completion():
- return self.client.chat.completions.create(
- model="Pro/deepseek-ai/DeepSeek-R1",
- messages=[{"role": "user", "content": prompt}],
- stream=False,
- max_tokens=1024
- )
-
+ return self.client.chat.completions.create(**default_params)
+
loop = asyncio.get_event_loop()
response = await loop.run_in_executor(None, create_completion)
- if response.choices[0].message.content:
- content = response.choices[0].message.content
- # 获取推理内容
- reasoning_content = "模型思考过程:\n" + prompt
- if hasattr(response.choices[0].message, "reasoning"):
- reasoning_content = response.choices[0].message.reasoning or reasoning_content
- elif hasattr(response.choices[0].message, "reasoning_content"):
- reasoning_content = response.choices[0].message.reasoning_content or reasoning_content
-
- # 保存推理结果到数据库
- self.db.db.reasoning_logs.insert_one({
- 'time': time.time(),
- 'group_id': message.group_id,
- 'user': sender_name,
- 'message': message.processed_plain_text,
- 'model': "DeepSeek-R1",
- 'reasoning': reasoning_content,
- 'response': content,
- 'prompt': prompt
- })
- else:
+
+ if not response.choices[0].message.content:
return None
+
+ content = response.choices[0].message.content
+
+ # 获取推理内容
+ reasoning_content = "模型思考过程:\n" + prompt
+ if hasattr(response.choices[0].message, "reasoning"):
+ reasoning_content = response.choices[0].message.reasoning or reasoning_content
+ elif hasattr(response.choices[0].message, "reasoning_content"):
+ reasoning_content = response.choices[0].message.reasoning_content or reasoning_content
+
+ # 保存到数据库
+ self.db.db.reasoning_logs.insert_one({
+ 'time': time.time(),
+ 'group_id': message.group_id,
+ 'user': sender_name,
+ 'message': message.processed_plain_text,
+ 'model': model_name,
+ 'reasoning': reasoning_content,
+ 'response': content,
+ 'prompt': prompt,
+ 'model_params': default_params
+ })
return content
+ async def _generate_r1_response(self, message: Message) -> Optional[str]:
+ """使用 DeepSeek-R1 模型生成回复"""
+ return await self._generate_base_response(
+ message,
+ "Pro/deepseek-ai/DeepSeek-R1",
+ {"temperature": 0.7, "max_tokens": 1024}
+ )
+
async def _generate_v3_response(self, message: Message) -> Optional[str]:
"""使用 DeepSeek-V3 模型生成回复"""
- # 获取群聊上下文
- group_chat = await self._get_group_chat_context(message)
- sender_name = message.user_nickname or f"用户{message.user_id}"
-
- if relationship_manager.get_relationship(message.user_id):
- relationship_value = relationship_manager.get_relationship(message.user_id).relationship_value
- print(f"\033[1;32m[关系管理]\033[0m 回复中_当前关系值: {relationship_value}")
- else:
- relationship_value = 0.0
-
- prompt = prompt_builder._build_prompt(message.processed_plain_text, sender_name, relationship_value, group_id=message.group_id)
-
- messages = [{"role": "user", "content": prompt}]
-
- loop = asyncio.get_event_loop()
- create_completion = partial(
- self.client.chat.completions.create,
- model="Pro/deepseek-ai/DeepSeek-V3",
- messages=messages,
- stream=False,
- max_tokens=1024,
- temperature=0.8
+ return await self._generate_base_response(
+ message,
+ "Pro/deepseek-ai/DeepSeek-V3",
+ {"temperature": 0.8, "max_tokens": 1024}
)
- response = await loop.run_in_executor(None, create_completion)
-
- if response.choices[0].message.content:
- content = response.choices[0].message.content
- # 保存推理结果到数据库
- self.db.db.reasoning_logs.insert_one({
- 'time': time.time(),
- 'group_id': message.group_id,
- 'user': sender_name,
- 'message': message.processed_plain_text,
- 'model': "DeepSeek-V3",
- 'reasoning': "V3模型无推理过程",
- 'response': content,
- 'prompt': prompt
- })
-
- return content
- else:
- print(f"[ERROR] V3 回复发送生成失败: {response}")
-
- return None
async def _generate_r1_distill_response(self, message: Message) -> Optional[str]:
"""使用 DeepSeek-R1-Distill-Qwen-32B 模型生成回复"""
- # 获取群聊上下文
- group_chat = await self._get_group_chat_context(message)
- sender_name = message.user_nickname or f"用户{message.user_id}"
- if relationship_manager.get_relationship(message.user_id):
- relationship_value = relationship_manager.get_relationship(message.user_id).relationship_value
- print(f"\033[1;32m[关系管理]\033[0m 回复中_当前关系值: {relationship_value}")
- else:
- relationship_value = 0.0
-
- # 构建 prompt
- prompt = prompt_builder._build_prompt(
- message_txt=message.processed_plain_text,
- sender_name=sender_name,
- relationship_value=relationship_value,
- group_id=message.group_id
+ return await self._generate_base_response(
+ message,
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
+ {"temperature": 0.7, "max_tokens": 1024}
)
-
- def create_completion():
- return self.client.chat.completions.create(
- model="deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
- messages=[{"role": "user", "content": prompt}],
- stream=False,
- max_tokens=1024
- )
-
- loop = asyncio.get_event_loop()
- response = await loop.run_in_executor(None, create_completion)
- if response.choices[0].message.content:
- content = response.choices[0].message.content
- # 获取推理内容
- reasoning_content = "模型思考过程:\n" + prompt
- if hasattr(response.choices[0].message, "reasoning"):
- reasoning_content = response.choices[0].message.reasoning or reasoning_content
- elif hasattr(response.choices[0].message, "reasoning_content"):
- reasoning_content = response.choices[0].message.reasoning_content or reasoning_content
-
- # 保存推理结果到数据库
- self.db.db.reasoning_logs.insert_one({
- 'time': time.time(),
- 'group_id': message.group_id,
- 'user': sender_name,
- 'message': message.processed_plain_text,
- 'model': "DeepSeek-R1-Distill",
- 'reasoning': reasoning_content,
- 'response': content,
- 'prompt': prompt
- })
- else:
- return None
-
-
- return content
async def _get_group_chat_context(self, message: Message) -> str:
"""获取群聊上下文"""
@@ -271,46 +213,14 @@ class LLMResponseGenerator:
print(f"获取情感标签时出错: {e}")
return ["neutral"] # 发生错误时返回默认值
- async def _process_response(self, content: str) -> Tuple[Union[str, List[str]], List[str]]:
+ async def _process_response(self, content: str) -> Tuple[List[str], List[str]]:
"""处理响应内容,返回处理后的内容和情感标签"""
if not content:
return None, []
- # 检查回复是否过长(超过200个字符)
- if len(content) > 200:
- print(f"回复过长 ({len(content)} 字符),返回默认回复")
- return "麦麦不知道哦", ["angry"]
-
emotion_tags = await self._get_emotion_tags(content)
-
- # 添加错别字和处理标点符号
- processed_response = process_text_with_typos(content)
-
- # 处理长消息
- if len(processed_response) > 5:
- sentences = split_into_sentences(processed_response)
- print(f"分割后的句子: {sentences}")
- messages = []
- current_message = ""
-
- for sentence in sentences:
- if len(current_message) + len(sentence) <= 5:
- current_message += ' '
- current_message += sentence
- else:
- if current_message:
- messages.append(current_message.strip())
- current_message = sentence
-
- if current_message:
- messages.append(current_message.strip())
-
- # 检查分割后的消息数量是否过多(超过3条)
- if len(messages) > 3:
- print(f"分割后消息数量过多 ({len(messages)} 条),返回默认回复")
- return "麦麦不知道哦", ["angry"]
-
- return messages, emotion_tags
+
+ processed_response = process_llm_response(content)
return processed_response, emotion_tags
diff --git a/src/plugins/chat/message.py b/src/plugins/chat/message.py
index 0b2479dac..a13a309db 100644
--- a/src/plugins/chat/message.py
+++ b/src/plugins/chat/message.py
@@ -9,6 +9,7 @@ from PIL import Image
from .config import BotConfig, global_config
import urllib3
from .cq_code import CQCode
+from .utils_user import get_user_nickname
Message = ForwardRef('Message') # 添加这行
@@ -44,32 +45,19 @@ class Message:
time: float = None
is_emoji: bool = False # 是否是表情包
+ has_emoji: bool = False # 是否包含表情包
-
reply_benefits: float = 0.0
type: str = 'received' # 消息类型,可以是received或者send
-
-
- """消息数据类:思考消息"""
-
- # 思考状态相关属性
- is_thinking: bool = False
- thinking_text: str = "正在思考..."
- thingking_start_time: float = None
- thinking_time: float = 0
-
- received_message = ''
- thinking_response = ''
-
def __post_init__(self):
if self.time is None:
self.time = int(time.time())
if not self.user_nickname:
- self.user_nickname = self.get_user_nickname(self.user_id)
+ self.user_nickname = get_user_nickname(self.user_id)
if not self.group_name:
self.group_name = self.get_groupname(self.group_id)
@@ -84,28 +72,6 @@ class Message:
for seg in self.message_segments
)
- # print(f"\033[1;34m[调试]\033[0m pppttt消息: {self.processed_plain_text}")
- def get_user_nickname(self, user_id: int) -> str:
- """
- 根据user_id获取用户昵称
- 如果数据库中找不到,则返回默认昵称
- """
- if not user_id:
- return "未知用户"
-
- user_id = int(user_id)
- if user_id == int(global_config.BOT_QQ):
- return "麦麦"
-
- # 使用数据库单例
- db = Database.get_instance()
- # 查找用户,打印查询条件和结果
- query = {'user_id': user_id}
- user = db.db.user_info.find_one(query)
- if user:
- return user.get('nickname') or f"用户{user_id}"
- else:
- return f"用户{user_id}"
def get_groupname(self, group_id: int) -> str:
if not group_id:
@@ -127,7 +93,7 @@ class Message:
返回的列表中每个元素都是字典,包含:
- type: 'text' 或 CQ码类型
- data: 对于text类型是文本内容,对于CQ码是参数字典
- - translated_text: 经过处理(如AI翻译)后的文本
+ - translated_text: 经过处理后的文本
"""
segments = []
start = 0
@@ -199,12 +165,16 @@ class Message:
})
start = cq_end + 1
-
- # 检查是否只包含一个表情包CQ码
+
+
if len(segments) == 1 and segments[0]['type'] == 'image':
- # 检查图片的 subtype 是否为 0(表情包)
- if segments[0]['data'].get('subtype') == '0':
- self.is_emoji = True
+ self.is_emoji = True
+ self.has_emoji_emoji = True
+ else:
+ for segment in segments:
+ if segment['type'] == 'image' and segment['data'].get('sub_type') == '1':
+ self.has_emoji_emoji = True
+ break
return segments
@@ -223,11 +193,6 @@ 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
@@ -278,21 +243,6 @@ class MessageSet:
return self.messages[left]
- def get_latest_message(self) -> Optional[Message]:
- """获取最新的消息"""
- return self.messages[-1] if self.messages else None
-
- def get_earliest_message(self) -> Optional[Message]:
- """获取最早的消息"""
- return self.messages[0] if self.messages else None
-
- def get_all_messages(self) -> List[Message]:
- """获取所有消息"""
- return self.messages.copy()
-
- def get_message_count(self) -> int:
- """获取消息数量"""
- return len(self.messages)
def clear_messages(self) -> None:
"""清空所有消息"""
@@ -311,10 +261,7 @@ class MessageSet:
def __len__(self) -> int:
return len(self.messages)
- @property
- def processed_plain_text(self) -> str:
- """获取所有消息的文本内容"""
- return "\n".join(msg.processed_plain_text for msg in self.messages if msg.processed_plain_text)
+
diff --git a/src/plugins/chat/message_send_control.py b/src/plugins/chat/message_send_control.py
index 40f1a9609..afbc3cd62 100644
--- a/src/plugins/chat/message_send_control.py
+++ b/src/plugins/chat/message_send_control.py
@@ -6,7 +6,7 @@ from .message import Message, Message_Thinking, MessageSet
from .cq_code import CQCode
from collections import deque
import time
-from .storage import MessageStorage # 添加这行导入
+from .storage import MessageStorage
from .config import global_config
from .message_visualizer import message_visualizer
@@ -29,18 +29,18 @@ class SendTemp:
if message.time >= self.messages[-1].time:
self.messages.append(message)
return
-
+
# 使用二分查找找到合适的插入位置
messages_list = list(self.messages)
left, right = 0, len(messages_list)
-
+
while left < right:
mid = (left + right) // 2
if messages_list[mid].time < message.time:
left = mid + 1
else:
right = mid
-
+
# 重建消息队列,保持时间顺序
new_messages = deque(maxlen=self.max_size)
new_messages.extend(messages_list[:left])
@@ -50,11 +50,6 @@ class SendTemp:
def get_earliest_message(self) -> Optional[Message]:
"""获取时间最早的消息"""
message = self.messages.popleft() if self.messages else None
- # 如果是思考中的消息且思考时间不够,重新加入队列
- # if (isinstance(message, Message_Thinking) and
- # time.time() - message.start_time < 2): # 最少思考2秒
- # self.messages.appendleft(message)
- # return None
return message
def clear(self) -> None:
@@ -120,16 +115,7 @@ class SendTempContainer:
return list(self.temp_queues.keys())
def update_thinking_message(self, message_obj: Union[Message, MessageSet]) -> bool:
- """更新思考中的消息
-
- Args:
- message_obj: 要更新的消息对象,可以是单条消息或消息组
-
- Returns:
- bool: 更新是否成功
- """
queue = self.get_queue(message_obj.group_id)
-
# 使用列表解析找到匹配的消息索引
matching_indices = [
i for i, msg in enumerate(queue.messages)
@@ -181,149 +167,66 @@ class MessageSendControl:
"""设置当前bot实例"""
self._current_bot = bot
+ async def process_group_messages(self, group_id: int):
+ queue = self.send_temp_container.get_queue(group_id)
+ if queue.has_messages():
+ message = queue.peek_next()
+ # 处理消息的逻辑
+ if isinstance(message, Message_Thinking):
+ 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}秒")
+ return
+ else:
+ print(f"\033[1;34m[调试]\033[0m 思考消息超时,移除")
+ queue.get_earliest_message() # 移除超时的思考消息
+ return
+ elif isinstance(message, Message):
+ message = queue.get_earliest_message()
+ if message and message.processed_plain_text:
+ print(f"- 群组: {group_id} - 内容: {message.processed_plain_text}")
+ cost_time = round(time.time(), 2) - message.time
+ if cost_time > 40:
+ message.processed_plain_text = CQCode.create_reply_cq(message.message_based_id) + message.processed_plain_text
+ 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)}")
+ await self.storage.store_message(message, None)
+ queue.update_send_time()
+ if queue.has_messages():
+ await asyncio.sleep(
+ random.uniform(
+ self.message_interval[0],
+ self.message_interval[1]
+ )
+ )
+
async def start_processor(self, bot: Bot):
"""启动消息处理器"""
self._current_bot = bot
while self._running:
- await asyncio.sleep(1.5)
- # 处理所有群组的消息队列
+ await asyncio.sleep(1.5)
+ tasks = []
for group_id in self.send_temp_container.get_all_groups():
- queue = self.send_temp_container.get_queue(group_id)
- if queue.has_messages():
- message = queue.peek_next()
- # print(f"\033[1;34m[调试]\033[0m 查看最早的消息: {message}")
- if message:
- if isinstance(message, Message_Thinking):
- # 如果是思考中的消息,检查是否需要继续等待
- 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}秒")
- continue
- else:
- print(f"\033[1;34m[调试]\033[0m 思考消息超时,移除")
- queue.get_earliest_message() # 移除超时的思考消息
-
- elif isinstance(message, Message):
- message = queue.get_earliest_message()
- if message and message.processed_plain_text:
- print(f"- 群组: {group_id} - 内容: {message.processed_plain_text}")
-
- cost_time = round(time.time(), 2) - message.time
- # print(f"\033[1;34m[调试]\033[0m 消息发送111111时间: {cost_time}秒")
- if cost_time > 40:
- message.processed_plain_text = CQCode.create_reply_cq(message.message_based_id) + message.processed_plain_text
-
-
-
- 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)}")
- await self.storage.store_message(message, None)
-
- queue.update_send_time()
-
- if queue.has_messages():
- await asyncio.sleep(
- random.uniform(
- self.message_interval[0],
- self.message_interval[1]
- )
- )
- message_visualizer.update_content(self.send_temp_container)
-
-
- async def process_group_queue(self, bot: Bot, group_id: int) -> None:
- """处理指定群组的消息队列"""
- queue = self.send_temp_container.get_queue(group_id)
- while queue.has_messages():
- message = queue.get_earliest_message()
- if message and message.processed_plain_text:
- await self.send_message(
- bot=bot,
- group_id=group_id,
- content=message.processed_plain_text
- )
- queue.update_send_time()
-
- if queue.has_messages():
- await asyncio.sleep(
- random.uniform(self.message_interval[0], self.message_interval[1])
- )
-
- async def process_all_queues(self, bot: Bot) -> None:
- """处理所有群组的消息队列"""
- if not self._running or self._paused:
- return
+ tasks.append(self.process_group_messages(group_id))
- for group_id in self.send_temp_container.get_all_groups():
- await self.process_group_queue(bot, group_id)
-
- async def send_temp_message(self,
- bot: Bot,
- group_id: int,
- message: Union[Message, Message_Thinking],
- with_emoji: bool = False,
- emoji_path: Optional[str] = None) -> bool:
- """
- 发送单个临时消息
- Args:
- bot: Bot实例
- group_id: 群组ID
- message: Message对象
- with_emoji: 是否带表情
- emoji_path: 表情图片路径
- Returns:
- bool: 发送是否成功
- """
- try:
- if with_emoji and emoji_path:
- return await self.send_with_emoji(
- bot=bot,
- group_id=group_id,
- text_content=message.processed_plain_text,
- emoji_path=emoji_path
- )
- else:
- return await self.send_message(
- bot=bot,
- group_id=group_id,
- content=message.processed_plain_text
- )
- except Exception as e:
- print(f"\033[1;31m[错误]\033[0m 发送临时消息失败: {str(e)}")
- return False
+ # 并行处理所有群组的消息
+ await asyncio.gather(*tasks)
+ message_visualizer.update_content(self.send_temp_container)
def set_typing_speed(self, min_speed: float, max_speed: float):
"""设置打字速度范围"""
self.typing_speed = (min_speed, max_speed)
-
- def set_message_interval(self, min_interval: float, max_interval: float):
- """设置消息间隔范围"""
- self.message_interval = (min_interval, max_interval)
-
- def pause(self):
- """暂停消息处理"""
- self._paused = True
-
- def resume(self):
- """恢复消息处理"""
- self._paused = False
-
- def stop(self):
- """停止消息处理"""
- self._running = False
# 创建全局实例
message_sender = MessageSendControl()
diff --git a/src/plugins/chat/message_visualizer.py b/src/plugins/chat/message_visualizer.py
index 2dd3f98e7..0469af8f6 100644
--- a/src/plugins/chat/message_visualizer.py
+++ b/src/plugins/chat/message_visualizer.py
@@ -92,7 +92,7 @@ class MessageVisualizer:
display_text += f"群组: {msg.group_id}\n"
display_text += f"用户: {msg.user_nickname}({msg.user_id})\n"
display_text += f"内容: {msg.thinking_text}\n"
- display_text += f"思考时间: {msg.thinking_time}秒\n"
+ display_text += f"思考时间: {int(msg.thinking_time)}秒\n"
else:
display_text += f"类型: 普通消息\n"
display_text += f"时间: {msg_time}\n"
diff --git a/src/plugins/chat/prompt_builder.py b/src/plugins/chat/prompt_builder.py
index c0f3a8aed..a96d93393 100644
--- a/src/plugins/chat/prompt_builder.py
+++ b/src/plugins/chat/prompt_builder.py
@@ -76,7 +76,7 @@ class PromptBuilder:
activate_prompt = ''
activate_prompt = f"以上是群里正在进行的聊天,昵称为 '{sender_name}' 的用户说的:{message_txt}。引起了你的注意,你和他{relation_prompt},你想要{relation_prompt_2}。"
- # 检测机器人相关词汇
+ #检测机器人相关词汇
bot_keywords = ['人机', 'bot', '机器', '入机', 'robot', '机器人']
is_bot = any(keyword in message_txt.lower() for keyword in bot_keywords)
if is_bot:
@@ -90,17 +90,29 @@ class PromptBuilder:
if personality_choice < 4/6: # 第一种人格
prompt_personality = f'''你的网名叫麦麦,是一个学习地质的女大学生,喜欢摄影,你会刷贴吧,你正在浏览qq群,{promt_info_prompt},
{activate_prompt}
- 现在请你给出日常且口语化的回复,平淡一些,尽量简短一些,不要输出感叹号。{is_bot_prompt}
+ 现在请你给出日常且口语化的回复,平淡一些,尽量简短一些。{is_bot_prompt}
请注意把握群里的聊天内容,不要回复的太有条理,可以有个性。'''
elif personality_choice < 1: # 第二种人格
prompt_personality = f'''你的网名叫麦麦,是一个女大学生,你有黑色头发,你会刷小红书, 你正在浏览qq群,{promt_info_prompt},
{activate_prompt}
- 现在请你给出日常且口语化的回复,请表现你自己的见解,不要一昧迎合,尽量简短一些,不要输出感叹号。{is_bot_prompt}
+ 现在请你给出日常且口语化的回复,请表现你自己的见解,不要一昧迎合,尽量简短一些。{is_bot_prompt}
请你表达自己的见解和观点。可以有个性。'''
+
+ #中文高手
+ prompt_ger = ''
+ if random.random() < 0.04:
+ prompt_ger += '你喜欢用倒装句'
+ if random.random() < 0.02:
+ prompt_ger += '你喜欢用反问句'
+ if random.random() < 0.01:
+ prompt_ger += '你喜欢用文言文'
+
#额外信息要求
extra_info = '''但是记得回复平淡一些,简短一些,不要过多提及自身的背景, 记住不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只需要输出回复内容就好,不要输出其他任何内容'''
+
+
#合并prompt
prompt = ""
# prompt += f"{prompt_info}\n"
@@ -108,6 +120,7 @@ class PromptBuilder:
prompt += f"{chat_talking_prompt}\n"
# prompt += f"{activate_prompt}\n"
prompt += f"{prompt_personality}\n"
+ prompt += f"{prompt_ger}\n"
prompt += f"{extra_info}\n"
return prompt
diff --git a/src/plugins/chat/relationship_manager.py b/src/plugins/chat/relationship_manager.py
index 15024e374..7ee7db7ae 100644
--- a/src/plugins/chat/relationship_manager.py
+++ b/src/plugins/chat/relationship_manager.py
@@ -46,8 +46,8 @@ class Relationship:
class RelationshipManager:
def __init__(self):
self.relationships: dict[int, Relationship] = {} # user_id -> Relationship
- #保存 qq号,现在使用昵称,别称
- self.id_name_nickname_table: dict[str, str, list] = {} # name -> [nickname, nickname, ...]
+ # self.id_name_nickname_table: dict[str, list] = {} # name -> [nickname, nickname, ...]
+ # print("[关系管理] 初始化 id_name_nickname_table") # 调试信息
async def update_relationship(self, user_id: int, data=None, **kwargs):
# 检查是否在内存中已存在
@@ -67,6 +67,9 @@ class RelationshipManager:
relationship = Relationship(user_id, data=data) if isinstance(data, dict) else Relationship(user_id, **kwargs)
self.relationships[user_id] = relationship
+ # 更新 id_name_nickname_table
+ # self.id_name_nickname_table[user_id] = [relationship.nickname] # 别称设置为空列表
+
# 保存到数据库
await self.storage_relationship(relationship)
relationship.saved = True
@@ -149,31 +152,12 @@ class RelationshipManager:
}},
upsert=True
)
-
- @staticmethod
- async def get_user_nickname(bot: Bot, user_id: int, group_id: int = None) -> Tuple[str, Optional[str]]:
- """
- 通过QQ API获取用户昵称
- """
-
- # 获取QQ昵称
- stranger_info = await bot.get_stranger_info(user_id=user_id)
- qq_nickname = stranger_info['nickname']
- # 如果提供了群号,获取群昵称
- if group_id:
- try:
- member_info = await bot.get_group_member_info(
- group_id=group_id,
- user_id=user_id,
- no_cache=True
- )
- group_nickname = member_info['card'] or None
- return qq_nickname, group_nickname
- except:
- return qq_nickname, None
-
- return qq_nickname, None
+ def get_name(self, user_id: int) -> str:
+ if user_id in self.relationships:
+ return self.relationships[user_id].nickname
+ else:
+ return "[某人]"
def print_all_relationships(self):
"""打印内存中所有的关系记录"""
@@ -193,8 +177,4 @@ class RelationshipManager:
print("=" * 50)
-
-
-
-
relationship_manager = RelationshipManager()
\ No newline at end of file
diff --git a/src/plugins/chat/utils.py b/src/plugins/chat/utils.py
index 96e842114..438475a8f 100644
--- a/src/plugins/chat/utils.py
+++ b/src/plugins/chat/utils.py
@@ -5,6 +5,8 @@ from .message import Message
import requests
import numpy as np
from .config import llm_config
+import re
+
def combine_messages(messages: List[Message]) -> str:
"""将消息列表组合成格式化的字符串
@@ -115,52 +117,85 @@ def get_recent_group_messages(db, group_id: int, limit: int = 12) -> list:
message_objects.reverse()
return message_objects
-def split_into_sentences(text: str) -> List[str]:
+def split_into_sentences_w_remove_punctuation(text: str) -> List[str]:
"""将文本分割成句子,但保持书名号中的内容完整
-
Args:
text: 要分割的文本字符串
-
Returns:
List[str]: 分割后的句子列表
"""
- delimiters = ['。', '!', ',', ',', '?', '…', '!', '?', '\n'] # 添加换行符作为分隔符
- remove_chars = [',', ','] # 只移除这两种逗号
- sentences = []
- current_sentence = ""
- in_book_title = False # 标记是否在书名号内
+ len_text = len(text)
+ if len_text < 5:
+ if random.random() < 0.01:
+ return list(text) # 如果文本很短且触发随机条件,直接按字符分割
+ else:
+ return [text]
+ if len_text < 12:
+ split_strength = 0.3
+ elif len_text < 32:
+ split_strength = 0.7
+ else:
+ split_strength = 0.9
+ #先移除换行符
+ # print(f"split_strength: {split_strength}")
- for char in text:
- current_sentence += char
+ # print(f"处理前的文本: {text}")
+
+ # 统一将英文逗号转换为中文逗号
+ text = text.replace(',', ',')
+ text = text.replace('\n', ' ')
+
+ # print(f"处理前的文本: {text}")
+
+ text_no_1 = ''
+ for letter in text:
+ # print(f"当前字符: {letter}")
+ if letter in ['!','!','?','?']:
+ # print(f"当前字符: {letter}, 随机数: {random.random()}")
+ if random.random() < split_strength:
+ letter = ''
+ if letter in ['。','…']:
+ # print(f"当前字符: {letter}, 随机数: {random.random()}")
+ if random.random() < 1 - split_strength:
+ letter = ''
+ text_no_1 += letter
- # 检查书名号
- if char == '《':
- in_book_title = True
- elif char == '》':
- in_book_title = False
+ # 对每个逗号单独判断是否分割
+ sentences = [text_no_1]
+ new_sentences = []
+ for sentence in sentences:
+ parts = sentence.split(',')
+ current_sentence = parts[0]
+ for part in parts[1:]:
+ if random.random() < split_strength:
+ new_sentences.append(current_sentence.strip())
+ current_sentence = part
+ else:
+ current_sentence += ',' + part
+ # 处理空格分割
+ space_parts = current_sentence.split(' ')
+ current_sentence = space_parts[0]
+ for part in space_parts[1:]:
+ if random.random() < split_strength:
+ new_sentences.append(current_sentence.strip())
+ current_sentence = part
+ else:
+ current_sentence += ' ' + part
+ new_sentences.append(current_sentence.strip())
+ sentences = [s for s in new_sentences if s] # 移除空字符串
+
+ # print(f"分割后的句子: {sentences}")
+ sentences_done = []
+ for sentence in sentences:
+ sentence = sentence.rstrip(',,')
+ if random.random() < split_strength*0.5:
+ sentence = sentence.replace(',', '').replace(',', '')
+ elif random.random() < split_strength:
+ sentence = sentence.replace(',', ' ').replace(',', ' ')
+ sentences_done.append(sentence)
- # 只有不在书名号内且是分隔符时才分割
- if char in delimiters and not in_book_title:
- if current_sentence.strip(): # 确保不是空字符串
- # 只移除逗号
- clean_sentence = current_sentence
- if clean_sentence[-1] in remove_chars:
- clean_sentence = clean_sentence[:-1]
- if clean_sentence.strip():
- sentences.append(clean_sentence.strip())
- current_sentence = ""
-
- # 处理最后一个句子
- if current_sentence.strip():
- # 如果最后一个字符是逗号,移除它
- if current_sentence[-1] in remove_chars:
- current_sentence = current_sentence[:-1]
- sentences.append(current_sentence.strip())
-
- # 过滤掉空字符串
- sentences = [s for s in sentences if s.strip()]
-
- return sentences
+ print(f"处理后的句子: {sentences_done}")
+ return sentences_done
# 常见的错别字映射
TYPO_DICT = {
@@ -259,16 +294,7 @@ def random_remove_punctuation(text: str) -> str:
return result
def add_typos(text: str) -> str:
- """随机给文本添加错别字
-
- Args:
- text: 要处理的文本
-
- Returns:
- str: 添加错别字后的文本
- """
TYPO_RATE = 0.02 # 控制错别字出现的概率(2%)
-
result = ""
for char in text:
if char in TYPO_DICT and random.random() < TYPO_RATE:
@@ -279,15 +305,33 @@ def add_typos(text: str) -> str:
result += char
return result
-def process_text_with_typos(text: str) -> str:
- """处理文本,添加错别字和处理标点符号
+def process_llm_response(text: str) -> List[str]:
+ # processed_response = process_text_with_typos(content)
+ if len(text) > 200:
+ print(f"回复过长 ({len(text)} 字符),返回默认回复")
+ return ['懒得说']
+ # 处理长消息
+ sentences = split_into_sentences_w_remove_punctuation(add_typos(text))
+ # 检查分割后的消息数量是否过多(超过3条)
+ if len(sentences) > 3:
+ print(f"分割后消息数量过多 ({len(sentences)} 条),返回默认回复")
+ return ['麦麦不知道哦']
- Args:
- text: 要处理的文本
-
- Returns:
- str: 处理后的文本
+ return sentences
+
+def calculate_typing_time(input_string: str, chinese_time: float = 0.2, english_time: float = 0.1) -> float:
"""
- if random.random() < 0.9: # 90%概率进行处理
- return random_remove_punctuation(add_typos(text))
- return text
+ 计算输入字符串所需的时间,中文和英文字符有不同的输入时间
+ input_string (str): 输入的字符串
+ chinese_time (float): 中文字符的输入时间,默认为0.3秒
+ english_time (float): 英文字符的输入时间,默认为0.15秒
+ """
+ total_time = 0.0
+ for char in input_string:
+ if '\u4e00' <= char <= '\u9fff': # 判断是否为中文字符
+ total_time += chinese_time
+ else: # 其他字符(如英文)
+ total_time += english_time
+ return total_time
+
+
diff --git a/src/plugins/chat/utils_user.py b/src/plugins/chat/utils_user.py
new file mode 100644
index 000000000..d4f1575d3
--- /dev/null
+++ b/src/plugins/chat/utils_user.py
@@ -0,0 +1,7 @@
+from .relationship_manager import relationship_manager
+from .config import global_config
+
+def get_user_nickname(user_id: int) -> str:
+ if user_id == int(global_config.BOT_QQ):
+ return global_config.BOT_NICKNAME
+ return relationship_manager.get_name(user_id)
\ No newline at end of file
diff --git a/src/plugins/chat/willing_manager.py b/src/plugins/chat/willing_manager.py
index 357c64656..79d23606f 100644
--- a/src/plugins/chat/willing_manager.py
+++ b/src/plugins/chat/willing_manager.py
@@ -27,12 +27,12 @@ class WillingManager:
current_willing = self.group_reply_willing.get(group_id, 0)
if topic and current_willing < 1:
- current_willing += 0.4
+ current_willing += 0.3
elif topic:
current_willing += 0.05
if is_mentioned_bot and current_willing < 1.0:
- current_willing += 1
+ current_willing += 0.9
elif is_mentioned_bot:
current_willing += 0.05
@@ -47,7 +47,7 @@ class WillingManager:
reply_probability = 0
if group_id in config.talk_frequency_down_groups:
- reply_probability = reply_probability / 2
+ reply_probability = reply_probability / 3.5
if is_mentioned_bot and user_id == int(1026294844):
reply_probability = 1
@@ -62,9 +62,8 @@ class WillingManager:
def change_reply_willing_after_sent(self, group_id: int):
"""发送消息后提高群组的回复意愿"""
current_willing = self.group_reply_willing.get(group_id, 0)
- # 如果当前意愿小于1,增加0.3的意愿值
if current_willing < 1:
- self.group_reply_willing[group_id] = min(1, current_willing + 0.8)
+ self.group_reply_willing[group_id] = min(1, current_willing + 0.4)
async def ensure_started(self):
"""确保衰减任务已启动"""