This commit is contained in:
tcmofashi
2025-08-26 10:41:52 +08:00
110 changed files with 4965 additions and 7572 deletions

View File

@@ -166,7 +166,6 @@ class ChatAction:
chat_talking_prompt = build_readable_messages(
message_list_before_now,
replace_bot_name=True,
merge_messages=False,
timestamp_mode="normal_no_YMD",
read_mark=0.0,
truncate=True,
@@ -230,7 +229,6 @@ class ChatAction:
chat_talking_prompt = build_readable_messages(
message_list_before_now,
replace_bot_name=True,
merge_messages=False,
timestamp_mode="normal_no_YMD",
read_mark=0.0,
truncate=True,

View File

@@ -14,12 +14,10 @@ from src.chat.message_receive.storage import MessageStorage
from .s4u_watching_manager import watching_manager
import json
from .s4u_mood_manager import mood_manager
from src.person_info.relationship_builder_manager import relationship_builder_manager
from src.mais4u.s4u_config import s4u_config
from src.person_info.person_info import get_person_id
from .super_chat_manager import get_super_chat_manager
from .yes_or_no import yes_or_no_head
from src.mais4u.constant_s4u import ENABLE_S4U
logger = get_logger("S4U_chat")
@@ -166,7 +164,7 @@ class S4UChatManager:
return self.s4u_chats[chat_stream.stream_id]
if not ENABLE_S4U:
if not s4u_config.enable_s4u:
s4u_chat_manager = None
else:
s4u_chat_manager = S4UChatManager()
@@ -183,7 +181,6 @@ class S4UChat:
self.chat_stream = chat_stream
self.stream_id = chat_stream.stream_id
self.stream_name = get_chat_manager().get_stream_name(self.stream_id) or self.stream_id
self.relationship_builder = relationship_builder_manager.get_or_create_builder(self.stream_id)
# 两个消息队列
self._vip_queue = asyncio.PriorityQueue()
@@ -264,29 +261,29 @@ class S4UChat:
platform = message.message_info.platform
person_id = get_person_id(platform, user_id)
try:
is_gift = message.is_gift
is_superchat = message.is_superchat
# print(is_gift)
# print(is_superchat)
if is_gift:
await self.relationship_builder.build_relation(immediate_build=person_id)
# 安全地增加兴趣分如果person_id不存在则先初始化为1.0
current_score = self.interest_dict.get(person_id, 1.0)
self.interest_dict[person_id] = current_score + 0.1 * message.gift_count
elif is_superchat:
await self.relationship_builder.build_relation(immediate_build=person_id)
# 安全地增加兴趣分如果person_id不存在则先初始化为1.0
current_score = self.interest_dict.get(person_id, 1.0)
self.interest_dict[person_id] = current_score + 0.1 * float(message.superchat_price)
# try:
# is_gift = message.is_gift
# is_superchat = message.is_superchat
# # print(is_gift)
# # print(is_superchat)
# if is_gift:
# await self.relationship_builder.build_relation(immediate_build=person_id)
# # 安全地增加兴趣分如果person_id不存在则先初始化为1.0
# current_score = self.interest_dict.get(person_id, 1.0)
# self.interest_dict[person_id] = current_score + 0.1 * message.gift_count
# elif is_superchat:
# await self.relationship_builder.build_relation(immediate_build=person_id)
# # 安全地增加兴趣分如果person_id不存在则先初始化为1.0
# current_score = self.interest_dict.get(person_id, 1.0)
# self.interest_dict[person_id] = current_score + 0.1 * float(message.superchat_price)
# 添加SuperChat到管理器
super_chat_manager = get_super_chat_manager()
await super_chat_manager.add_superchat(message)
else:
await self.relationship_builder.build_relation(20)
except Exception:
traceback.print_exc()
# # 添加SuperChat到管理器
# super_chat_manager = get_super_chat_manager()
# await super_chat_manager.add_superchat(message)
# else:
# await self.relationship_builder.build_relation(20)
# except Exception:
# traceback.print_exc()
logger.info(f"[{self.stream_name}] 消息处理完毕,消息内容:{message.processed_plain_text}")

View File

@@ -10,7 +10,7 @@ from src.config.config import global_config, model_config
from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
from src.manager.async_task_manager import AsyncTask, async_task_manager
from src.plugin_system.apis import send_api
from src.mais4u.constant_s4u import ENABLE_S4U
from src.mais4u.s4u_config import s4u_config
"""
情绪管理系统使用说明:
@@ -166,10 +166,10 @@ class ChatMood:
limit=10,
limit_mode="last",
)
chat_talking_prompt = build_readable_messages(
message_list_before_now,
replace_bot_name=True,
merge_messages=False,
timestamp_mode="normal_no_YMD",
read_mark=0.0,
truncate=True,
@@ -245,10 +245,10 @@ class ChatMood:
limit=5,
limit_mode="last",
)
chat_talking_prompt = build_readable_messages(
message_list_before_now,
replace_bot_name=True,
merge_messages=False,
timestamp_mode="normal_no_YMD",
read_mark=0.0,
truncate=True,
@@ -447,7 +447,7 @@ class MoodManager:
asyncio.create_task(new_mood.send_emotion_update(new_mood.mood_values))
if ENABLE_S4U:
if s4u_config.enable_s4u:
init_prompt()
mood_manager = MoodManager()
else:

View File

@@ -40,7 +40,7 @@ async def _calculate_interest(message: MessageRecv) -> Tuple[float, bool]:
if global_config.memory.enable_memory:
with Timer("记忆激活"):
interested_rate,_ = await hippocampus_manager.get_activate_from_text(
interested_rate,_ ,_= await hippocampus_manager.get_activate_from_text(
message.processed_plain_text,
fast_retrieval=True,
)

View File

@@ -17,6 +17,10 @@ from src.mais4u.mais4u_chat.screen_manager import screen_manager
from src.chat.express.expression_selector import expression_selector
from .s4u_mood_manager import mood_manager
from src.mais4u.mais4u_chat.internal_manager import internal_manager
from src.common.data_models.database_data_model import DatabaseMessages
from typing import List
logger = get_logger("prompt")
@@ -58,7 +62,7 @@ def init_prompt():
""",
"s4u_prompt", # New template for private CHAT chat
)
Prompt(
"""
你的名字是麦麦, 是千石可乐开发的程序可以在QQ微信等平台发言你现在正在哔哩哔哩作为虚拟主播进行直播
@@ -95,14 +99,13 @@ class PromptBuilder:
def __init__(self):
self.prompt_built = ""
self.activate_messages = ""
async def build_expression_habits(self, chat_stream: ChatStream, chat_history, target):
async def build_expression_habits(self, chat_stream: ChatStream, chat_history, target):
style_habits = []
# 使用从处理器传来的选中表达方式
# LLM模式调用LLM选择5-10个然后随机选5个
selected_expressions ,_ = await expression_selector.select_suitable_expressions_llm(
selected_expressions, _ = await expression_selector.select_suitable_expressions_llm(
chat_stream.stream_id, chat_history, max_num=12, target_message=target
)
@@ -122,7 +125,6 @@ class PromptBuilder:
if style_habits_str.strip():
expression_habits_block += f"你可以参考以下的语言习惯,如果情景合适就使用,不要盲目使用,不要生硬使用,而是结合到表达中:\n{style_habits_str}\n\n"
return expression_habits_block
async def build_relation_info(self, chat_stream) -> str:
@@ -148,9 +150,7 @@ class PromptBuilder:
person_ids.append(person_id)
# 使用 Person 的 build_relationship 方法,设置 points_num=3 保持与原来相同的行为
relation_info_list = [
Person(person_id=person_id).build_relationship(points_num=3) for person_id in person_ids
]
relation_info_list = [Person(person_id=person_id).build_relationship() for person_id in person_ids]
if relation_info := "".join(relation_info_list):
relation_prompt = await global_prompt_manager.format_prompt(
"relation_prompt", relation_info=relation_info
@@ -158,6 +158,9 @@ class PromptBuilder:
return relation_prompt
async def build_memory_block(self, text: str) -> str:
# 待更新记忆系统
return ""
related_memory = await hippocampus_manager.get_memory_from_text(
text=text, max_memory_num=2, max_memory_length=2, max_depth=3, fast_retrieval=False
)
@@ -173,37 +176,37 @@ class PromptBuilder:
message_list_before_now = get_raw_msg_before_timestamp_with_chat(
chat_id=chat_stream.stream_id,
timestamp=time.time(),
# sourcery skip: lift-duplicated-conditional, merge-duplicate-blocks, remove-redundant-if
limit=300,
)
talk_type = f"{message.message_info.platform}:{str(message.chat_stream.user_info.user_id)}"
core_dialogue_list = []
background_dialogue_list = []
core_dialogue_list: List[DatabaseMessages] = []
background_dialogue_list: List[DatabaseMessages] = []
bot_id = str(global_config.bot.qq_account)
target_user_id = str(message.chat_stream.user_info.user_id)
for msg_dict in message_list_before_now:
for msg in message_list_before_now:
try:
msg_user_id = str(msg_dict.get("user_id"))
msg_user_id = str(msg.user_info.user_id)
if msg_user_id == bot_id:
if msg_dict.get("reply_to") and talk_type == msg_dict.get("reply_to"):
core_dialogue_list.append(msg_dict)
elif msg_dict.get("reply_to") and talk_type != msg_dict.get("reply_to"):
background_dialogue_list.append(msg_dict)
if msg.reply_to and talk_type == msg.reply_to:
core_dialogue_list.append(msg)
elif msg.reply_to and talk_type != msg.reply_to:
background_dialogue_list.append(msg)
# else:
# background_dialogue_list.append(msg_dict)
# background_dialogue_list.append(msg_dict)
elif msg_user_id == target_user_id:
core_dialogue_list.append(msg_dict)
core_dialogue_list.append(msg)
else:
background_dialogue_list.append(msg_dict)
background_dialogue_list.append(msg)
except Exception as e:
logger.error(f"无法处理历史消息记录: {msg_dict}, 错误: {e}")
logger.error(f"无法处理历史消息记录: {msg.__dict__}, 错误: {e}")
background_dialogue_prompt = ""
if background_dialogue_list:
context_msgs = background_dialogue_list[-s4u_config.max_context_message_length:]
context_msgs = background_dialogue_list[-s4u_config.max_context_message_length :]
background_dialogue_prompt_str = build_readable_messages(
context_msgs,
timestamp_mode="normal_no_YMD",
@@ -213,10 +216,10 @@ class PromptBuilder:
core_msg_str = ""
if core_dialogue_list:
core_dialogue_list = core_dialogue_list[-s4u_config.max_core_message_length:]
core_dialogue_list = core_dialogue_list[-s4u_config.max_core_message_length :]
first_msg = core_dialogue_list[0]
start_speaking_user_id = first_msg.get("user_id")
start_speaking_user_id = first_msg.user_info.user_id
if start_speaking_user_id == bot_id:
last_speaking_user_id = bot_id
msg_seg_str = "你的发言:\n"
@@ -225,13 +228,13 @@ class PromptBuilder:
last_speaking_user_id = start_speaking_user_id
msg_seg_str = "对方的发言:\n"
msg_seg_str += f"{time.strftime('%H:%M:%S', time.localtime(first_msg.get('time')))}: {first_msg.get('processed_plain_text')}\n"
msg_seg_str += f"{time.strftime('%H:%M:%S', time.localtime(first_msg.time))}: {first_msg.processed_plain_text}\n"
all_msg_seg_list = []
for msg in core_dialogue_list[1:]:
speaker = msg.get("user_id")
speaker = msg.user_info.user_id
if speaker == last_speaking_user_id:
msg_seg_str += f"{time.strftime('%H:%M:%S', time.localtime(msg.get('time')))}: {msg.get('processed_plain_text')}\n"
msg_seg_str += f"{time.strftime('%H:%M:%S', time.localtime(msg.time))}: {msg.processed_plain_text}\n"
else:
msg_seg_str = f"{msg_seg_str}\n"
all_msg_seg_list.append(msg_seg_str)
@@ -248,43 +251,40 @@ class PromptBuilder:
for msg in all_msg_seg_list:
core_msg_str += msg
all_dialogue_prompt = get_raw_msg_before_timestamp_with_chat(
all_dialogue_history = get_raw_msg_before_timestamp_with_chat(
chat_id=chat_stream.stream_id,
timestamp=time.time(),
limit=20,
)
all_dialogue_prompt_str = build_readable_messages(
all_dialogue_prompt,
all_dialogue_history,
timestamp_mode="normal_no_YMD",
show_pic=False,
)
return core_msg_str, background_dialogue_prompt,all_dialogue_prompt_str
return core_msg_str, background_dialogue_prompt, all_dialogue_prompt_str
def build_gift_info(self, message: MessageRecvS4U):
if message.is_gift:
return f"这是一条礼物信息,{message.gift_name} x{message.gift_count},请注意这位用户"
return f"这是一条礼物信息,{message.gift_name} x{message.gift_count},请注意这位用户"
else:
if message.is_fake_gift:
return f"{message.processed_plain_text}(注意:这是一条普通弹幕信息,对方没有真的发送礼物,不是礼物信息,注意区分,如果对方在发假的礼物骗你,请反击)"
return ""
def build_sc_info(self, message: MessageRecvS4U):
super_chat_manager = get_super_chat_manager()
return super_chat_manager.build_superchat_summary_string(message.chat_stream.stream_id)
async def build_prompt_normal(
self,
message: MessageRecvS4U,
message_txt: str,
) -> str:
chat_stream = message.chat_stream
person = Person(platform=message.chat_stream.user_info.platform, user_id=message.chat_stream.user_info.user_id)
person_name = person.person_name
@@ -295,28 +295,31 @@ class PromptBuilder:
sender_name = f"[{message.chat_stream.user_info.user_nickname}]"
else:
sender_name = f"用户({message.chat_stream.user_info.user_id})"
relation_info_block, memory_block, expression_habits_block = await asyncio.gather(
self.build_relation_info(chat_stream), self.build_memory_block(message_txt), self.build_expression_habits(chat_stream, message_txt, sender_name)
self.build_relation_info(chat_stream),
self.build_memory_block(message_txt),
self.build_expression_habits(chat_stream, message_txt, sender_name),
)
core_dialogue_prompt, background_dialogue_prompt, all_dialogue_prompt = self.build_chat_history_prompts(
chat_stream, message
)
core_dialogue_prompt, background_dialogue_prompt,all_dialogue_prompt = self.build_chat_history_prompts(chat_stream, message)
gift_info = self.build_gift_info(message)
sc_info = self.build_sc_info(message)
screen_info = screen_manager.get_screen_str()
internal_state = internal_manager.get_internal_state_str()
time_block = f"当前时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
mood = mood_manager.get_mood_by_chat_id(chat_stream.stream_id)
template_name = "s4u_prompt"
if not message.is_internal:
prompt = await global_prompt_manager.format_prompt(
template_name,
@@ -349,7 +352,7 @@ class PromptBuilder:
mind=message.processed_plain_text,
mood_state=mood.mood_state,
)
# print(prompt)
return prompt

View File

@@ -5,7 +5,7 @@ from typing import Dict, List, Optional
from src.common.logger import get_logger
from src.chat.message_receive.message import MessageRecvS4U
# 全局SuperChat管理器实例
from src.mais4u.constant_s4u import ENABLE_S4U
from src.mais4u.s4u_config import s4u_config
logger = get_logger("super_chat_manager")
@@ -299,7 +299,7 @@ class SuperChatManager:
# sourcery skip: assign-if-exp
if ENABLE_S4U:
if s4u_config.enable_s4u:
super_chat_manager = SuperChatManager()
else:
super_chat_manager = None