fix:修复引用回复逻辑
This commit is contained in:
@@ -82,15 +82,14 @@ class ChatBot:
|
||||
if userinfo.user_id in global_config.ban_user_id:
|
||||
logger.debug(f"用户{userinfo.user_id}被禁止回复")
|
||||
return
|
||||
|
||||
|
||||
if groupinfo is None:
|
||||
logger.trace("检测到私聊消息,检查")
|
||||
# 好友黑名单拦截
|
||||
# 好友黑名单拦截
|
||||
if userinfo.user_id not in global_config.talk_allowed_private:
|
||||
logger.debug(f"用户{userinfo.user_id}没有私聊权限")
|
||||
return
|
||||
|
||||
|
||||
# 群聊黑名单拦截
|
||||
if groupinfo is not None and groupinfo.group_id not in global_config.talk_allowed_groups:
|
||||
logger.trace(f"群{groupinfo.group_id}被禁止回复")
|
||||
|
||||
@@ -294,7 +294,9 @@ class MessageSending(MessageProcessBase):
|
||||
|
||||
def set_reply(self, reply: Optional["MessageRecv"] = None):
|
||||
"""设置回复消息"""
|
||||
if self.message_info.format_info is not None and "reply" in self.message_info.format_info.accept_format:
|
||||
# print(f"set_reply: {reply}")
|
||||
# if self.message_info.format_info is not None and "reply" in self.message_info.format_info.accept_format:
|
||||
if True:
|
||||
if reply:
|
||||
self.reply = reply
|
||||
if self.reply:
|
||||
|
||||
@@ -209,24 +209,31 @@ class MessageManager:
|
||||
_ = message.update_thinking_time() # 更新思考时间
|
||||
thinking_start_time = message.thinking_start_time
|
||||
now_time = time.time()
|
||||
logger.debug(f"thinking_start_time:{thinking_start_time},now_time:{now_time}")
|
||||
thinking_messages_count, thinking_messages_length = count_messages_between(
|
||||
start_time=thinking_start_time, end_time=now_time, stream_id=message.chat_stream.stream_id
|
||||
)
|
||||
# print(f"message.reply:{message.reply}")
|
||||
|
||||
# --- 条件应用 set_reply 逻辑 ---
|
||||
logger.debug(
|
||||
f"[message.apply_set_reply_logic:{message.apply_set_reply_logic},message.is_head:{message.is_head},thinking_messages_count:{thinking_messages_count},thinking_messages_length:{thinking_messages_length},message.is_private_message():{message.is_private_message()}]"
|
||||
)
|
||||
if (
|
||||
message.apply_set_reply_logic # 检查标记
|
||||
and message.is_head
|
||||
and (thinking_messages_count > 4 or thinking_messages_length > 250)
|
||||
and (thinking_messages_count > 1 or thinking_messages_length > 20)
|
||||
and not message.is_private_message()
|
||||
):
|
||||
logger.debug(
|
||||
f"[{message.chat_stream.stream_id}] 应用 set_reply 逻辑: {message.processed_plain_text[:20]}..."
|
||||
)
|
||||
message.set_reply()
|
||||
message.set_reply(message.reply)
|
||||
# --- 结束条件 set_reply ---
|
||||
|
||||
await message.process() # 预处理消息内容
|
||||
|
||||
logger.debug(f"{message}")
|
||||
|
||||
# 使用全局 message_sender 实例
|
||||
await send_message(message)
|
||||
|
||||
@@ -6,13 +6,13 @@ from collections import Counter
|
||||
import jieba
|
||||
import numpy as np
|
||||
from src.common.logger import get_module_logger
|
||||
from pymongo.errors import PyMongoError
|
||||
|
||||
from ..models.utils_model import LLMRequest
|
||||
from ..utils.typo_generator import ChineseTypoGenerator
|
||||
from ...config.config import global_config
|
||||
from .message import MessageRecv, Message
|
||||
from .message import MessageRecv
|
||||
from maim_message import UserInfo
|
||||
from .chat_stream import ChatStream
|
||||
from ..moods.moods import MoodManager
|
||||
from ...common.database import db
|
||||
|
||||
@@ -107,8 +107,6 @@ async def get_embedding(text, request_type="embedding"):
|
||||
return embedding
|
||||
|
||||
|
||||
|
||||
|
||||
def get_recent_group_detailed_plain_text(chat_stream_id: str, limit: int = 12, combine=False):
|
||||
recent_messages = list(
|
||||
db.messages.find(
|
||||
@@ -566,93 +564,45 @@ def count_messages_between(start_time: float, end_time: float, stream_id: str) -
|
||||
"""计算两个时间点之间的消息数量和文本总长度
|
||||
|
||||
Args:
|
||||
start_time (float): 起始时间戳
|
||||
end_time (float): 结束时间戳
|
||||
start_time (float): 起始时间戳 (不包含)
|
||||
end_time (float): 结束时间戳 (包含)
|
||||
stream_id (str): 聊天流ID
|
||||
|
||||
Returns:
|
||||
tuple[int, int]: (消息数量, 文本总长度)
|
||||
- 消息数量:包含起始时间的消息,不包含结束时间的消息
|
||||
- 文本总长度:所有消息的processed_plain_text长度之和
|
||||
"""
|
||||
count = 0
|
||||
total_length = 0
|
||||
|
||||
# 参数校验 (可选但推荐)
|
||||
if start_time >= end_time:
|
||||
# logger.debug(f"开始时间 {start_time} 大于或等于结束时间 {end_time},返回 0, 0")
|
||||
return 0, 0
|
||||
if not stream_id:
|
||||
logger.error("stream_id 不能为空")
|
||||
return 0, 0
|
||||
|
||||
# 直接查询时间范围内的消息
|
||||
# time > start_time AND time <= end_time
|
||||
query = {"chat_id": stream_id, "time": {"$gt": start_time, "$lte": end_time}}
|
||||
|
||||
try:
|
||||
# 获取开始时间之前最新的一条消息
|
||||
start_message = db.messages.find_one(
|
||||
{"chat_id": stream_id, "time": {"$lte": start_time}},
|
||||
sort=[("time", -1), ("_id", -1)], # 按时间倒序,_id倒序(最后插入的在前)
|
||||
)
|
||||
# 执行查询
|
||||
messages_cursor = db.messages.find(query)
|
||||
|
||||
# 获取结束时间最近的一条消息
|
||||
# 先找到结束时间点的所有消息
|
||||
end_time_messages = list(
|
||||
db.messages.find(
|
||||
{"chat_id": stream_id, "time": {"$lte": end_time}},
|
||||
sort=[("time", -1)], # 先按时间倒序
|
||||
).limit(10)
|
||||
) # 限制查询数量,避免性能问题
|
||||
|
||||
if not end_time_messages:
|
||||
logger.warning(f"未找到结束时间 {end_time} 之前的消息")
|
||||
return 0, 0
|
||||
|
||||
# 找到最大时间
|
||||
max_time = end_time_messages[0]["time"]
|
||||
# 在最大时间的消息中找最后插入的(_id最大的)
|
||||
end_message = max([msg for msg in end_time_messages if msg["time"] == max_time], key=lambda x: x["_id"])
|
||||
|
||||
if not start_message:
|
||||
logger.warning(f"未找到开始时间 {start_time} 之前的消息")
|
||||
return 0, 0
|
||||
|
||||
# 调试输出
|
||||
# print("\n=== 消息范围信息 ===")
|
||||
# print("Start message:", {
|
||||
# "message_id": start_message.get("message_id"),
|
||||
# "time": start_message.get("time"),
|
||||
# "text": start_message.get("processed_plain_text", ""),
|
||||
# "_id": str(start_message.get("_id"))
|
||||
# })
|
||||
# print("End message:", {
|
||||
# "message_id": end_message.get("message_id"),
|
||||
# "time": end_message.get("time"),
|
||||
# "text": end_message.get("processed_plain_text", ""),
|
||||
# "_id": str(end_message.get("_id"))
|
||||
# })
|
||||
# print("Stream ID:", stream_id)
|
||||
|
||||
# 如果结束消息的时间等于开始时间,返回0
|
||||
if end_message["time"] == start_message["time"]:
|
||||
return 0, 0
|
||||
|
||||
# 获取并打印这个时间范围内的所有消息
|
||||
# print("\n=== 时间范围内的所有消息 ===")
|
||||
all_messages = list(
|
||||
db.messages.find(
|
||||
{"chat_id": stream_id, "time": {"$gte": start_message["time"], "$lte": end_message["time"]}},
|
||||
sort=[("time", 1), ("_id", 1)], # 按时间正序,_id正序
|
||||
)
|
||||
)
|
||||
|
||||
count = 0
|
||||
total_length = 0
|
||||
for msg in all_messages:
|
||||
# 遍历结果计算数量和长度
|
||||
for msg in messages_cursor:
|
||||
count += 1
|
||||
text_length = len(msg.get("processed_plain_text", ""))
|
||||
total_length += text_length
|
||||
# print(f"\n消息 {count}:")
|
||||
# print({
|
||||
# "message_id": msg.get("message_id"),
|
||||
# "time": msg.get("time"),
|
||||
# "text": msg.get("processed_plain_text", ""),
|
||||
# "text_length": text_length,
|
||||
# "_id": str(msg.get("_id"))
|
||||
# })
|
||||
total_length += len(msg.get("processed_plain_text", ""))
|
||||
|
||||
# 如果时间不同,需要把end_message本身也计入
|
||||
return count - 1, total_length
|
||||
# logger.debug(f"查询范围 ({start_time}, {end_time}] 内找到 {count} 条消息,总长度 {total_length}")
|
||||
return count, total_length
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"计算消息数量时出错: {str(e)}")
|
||||
except PyMongoError as e:
|
||||
logger.error(f"查询 stream_id={stream_id} 在 ({start_time}, {end_time}] 范围内的消息时出错: {e}")
|
||||
return 0, 0
|
||||
except Exception as e: # 保留一个通用异常捕获以防万一
|
||||
logger.error(f"计算消息数量时发生意外错误: {e}")
|
||||
return 0, 0
|
||||
|
||||
|
||||
|
||||
@@ -372,6 +372,7 @@ class PromptBuilder:
|
||||
memory_prompt = await global_prompt_manager.format_prompt(
|
||||
"memory_prompt", related_memory_info=related_memory_info
|
||||
)
|
||||
|
||||
message_list_before_now = get_raw_msg_before_timestamp_with_chat(
|
||||
chat_id=chat_stream.stream_id,
|
||||
timestamp=time.time(),
|
||||
|
||||
@@ -86,11 +86,12 @@ class NormalChat:
|
||||
bot_user_info=bot_user_info,
|
||||
reply=message,
|
||||
thinking_start_time=thinking_time_point,
|
||||
timestamp=timestamp if timestamp is not None else None
|
||||
timestamp=timestamp if timestamp is not None else None,
|
||||
)
|
||||
|
||||
await message_manager.add_message(thinking_message)
|
||||
return thinking_id
|
||||
|
||||
# 改为实例方法
|
||||
async def _add_messages_to_manager(
|
||||
self, message: MessageRecv, response_set: List[str], thinking_id
|
||||
@@ -206,7 +207,10 @@ class NormalChat:
|
||||
try:
|
||||
# 处理消息
|
||||
await self.normal_response(
|
||||
message=message, is_mentioned=is_mentioned, interested_rate=interest_value, rewind_response = False
|
||||
message=message,
|
||||
is_mentioned=is_mentioned,
|
||||
interested_rate=interest_value,
|
||||
rewind_response=False,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"[{self.stream_name}] 处理兴趣消息{msg_id}时出错: {e}\n{traceback.format_exc()}")
|
||||
@@ -214,7 +218,9 @@ class NormalChat:
|
||||
self.interest_dict.pop(msg_id, None)
|
||||
|
||||
# 改为实例方法, 移除 chat 参数
|
||||
async def normal_response(self, message: MessageRecv, is_mentioned: bool, interested_rate: float, rewind_response: bool = False) -> None:
|
||||
async def normal_response(
|
||||
self, message: MessageRecv, is_mentioned: bool, interested_rate: float, rewind_response: bool = False
|
||||
) -> None:
|
||||
# 检查收到的消息是否属于当前实例处理的 chat stream
|
||||
if message.chat_stream.stream_id != self.stream_id:
|
||||
logger.error(
|
||||
@@ -393,13 +399,17 @@ class NormalChat:
|
||||
|
||||
try:
|
||||
logger.info(f"[{self.stream_name}] 处理初始高兴趣消息 {msg_id} (兴趣值: {interest_value:.2f})")
|
||||
await self.normal_response(message=message, is_mentioned=is_mentioned, interested_rate=interest_value, rewind_response = True)
|
||||
await self.normal_response(
|
||||
message=message, is_mentioned=is_mentioned, interested_rate=interest_value, rewind_response=True
|
||||
)
|
||||
processed_count += 1
|
||||
except Exception as e:
|
||||
logger.error(f"[{self.stream_name}] 处理初始兴趣消息 {msg_id} 时出错: {e}\\n{traceback.format_exc()}")
|
||||
|
||||
# --- 新增:处理完后清空整个字典 ---
|
||||
logger.info(f"[{self.stream_name}] 处理了 {processed_count} 条初始高兴趣消息。现在清空所有剩余的初始兴趣消息...")
|
||||
logger.info(
|
||||
f"[{self.stream_name}] 处理了 {processed_count} 条初始高兴趣消息。现在清空所有剩余的初始兴趣消息..."
|
||||
)
|
||||
self.interest_dict.clear()
|
||||
# --- 新增结束 ---
|
||||
|
||||
|
||||
@@ -188,7 +188,9 @@ class PersonInfoManager:
|
||||
logger.warning(f"无法从文本中提取有效的JSON字典: {text}")
|
||||
return {"nickname": "", "reason": ""}
|
||||
|
||||
async def qv_person_name(self, person_id: str, user_nickname: str, user_cardname: str, user_avatar: str, request: str = ""):
|
||||
async def qv_person_name(
|
||||
self, person_id: str, user_nickname: str, user_cardname: str, user_avatar: str, request: str = ""
|
||||
):
|
||||
"""给某个用户取名"""
|
||||
if not person_id:
|
||||
logger.debug("取名失败:person_id不能为空")
|
||||
@@ -214,7 +216,7 @@ class PersonInfoManager:
|
||||
qv_name_prompt += f"你之前叫他{old_name},是因为{old_reason},"
|
||||
|
||||
qv_name_prompt += f"\n其他取名的要求是:{request}"
|
||||
|
||||
|
||||
qv_name_prompt += "\n请根据以上用户信息,想想你叫他什么比较好,请最好使用用户的qq昵称,可以稍作修改"
|
||||
if existing_names:
|
||||
qv_name_prompt += f"\n请注意,以下名称已被使用,不要使用以下昵称:{existing_names}。\n"
|
||||
@@ -526,7 +528,7 @@ class PersonInfoManager:
|
||||
for pid, name in self.person_name_list.items():
|
||||
if name == person_name:
|
||||
found_person_id = pid
|
||||
break # 找到第一个匹配就停止
|
||||
break # 找到第一个匹配就停止
|
||||
|
||||
if not found_person_id:
|
||||
# 如果内存没有,尝试数据库查询(可能内存未及时更新或启动时未加载)
|
||||
@@ -535,21 +537,21 @@ class PersonInfoManager:
|
||||
found_person_id = document.get("person_id")
|
||||
else:
|
||||
logger.debug(f"数据库中也未找到名为 '{person_name}' 的用户")
|
||||
return None # 数据库也找不到
|
||||
return None # 数据库也找不到
|
||||
|
||||
# 根据找到的 person_id 获取所需信息
|
||||
if found_person_id:
|
||||
required_fields = ["person_id", "platform", "user_id", "nickname", "user_cardname", "user_avatar"]
|
||||
person_data = await self.get_values(found_person_id, required_fields)
|
||||
if person_data: # 确保 get_values 成功返回
|
||||
if person_data: # 确保 get_values 成功返回
|
||||
return person_data
|
||||
else:
|
||||
logger.warning(f"找到了 person_id '{found_person_id}' 但获取详细信息失败")
|
||||
return None
|
||||
else:
|
||||
# 这理论上不应该发生,因为上面已经处理了找不到的情况
|
||||
logger.error(f"逻辑错误:未能为 '{person_name}' 确定 person_id")
|
||||
return None
|
||||
# 这理论上不应该发生,因为上面已经处理了找不到的情况
|
||||
logger.error(f"逻辑错误:未能为 '{person_name}' 确定 person_id")
|
||||
return None
|
||||
|
||||
|
||||
person_info_manager = PersonInfoManager()
|
||||
|
||||
Reference in New Issue
Block a user