This commit is contained in:
SengokuCola
2025-07-03 12:26:01 +08:00
4 changed files with 37 additions and 39 deletions

View File

@@ -21,12 +21,12 @@ import re
# 定义日志配置 # 定义日志配置
# 获取项目根目录假设本文件在src/chat/message_receive/下,根目录为上上上级目录) # 获取项目根目录假设本文件在src/chat/message_receive/下,根目录为上上上级目录)
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../..')) PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../.."))
ENABLE_S4U_CHAT = os.path.isfile(os.path.join(PROJECT_ROOT, 's4u.s4u')) ENABLE_S4U_CHAT = os.path.isfile(os.path.join(PROJECT_ROOT, "s4u.s4u"))
if ENABLE_S4U_CHAT: if ENABLE_S4U_CHAT:
print('''\nS4U私聊模式已开启\n!!!!!!!!!!!!!!!!!\n''') print("""\nS4U私聊模式已开启\n!!!!!!!!!!!!!!!!!\n""")
# 仅内部开启 # 仅内部开启
# 配置主程序日志格式 # 配置主程序日志格式

View File

@@ -155,11 +155,6 @@ class S4UChat:
self._vip_queue = asyncio.PriorityQueue() self._vip_queue = asyncio.PriorityQueue()
self._normal_queue = asyncio.PriorityQueue() self._normal_queue = asyncio.PriorityQueue()
# 优先级管理配置
self.normal_queue_max_size = 20 # 普通队列最大容量,可以后续移到配置文件
self.interest_dict = {} # 用户兴趣分字典,可以后续移到配置文件. e.g. {"user_id": 5.0}
self.at_bot_priority_bonus = 100.0 # @机器人时的额外优先分
self._entry_counter = 0 # 保证FIFO的全局计数器 self._entry_counter = 0 # 保证FIFO的全局计数器
self._new_message_event = asyncio.Event() # 用于唤醒处理器 self._new_message_event = asyncio.Event() # 用于唤醒处理器
@@ -201,13 +196,12 @@ class S4UChat:
async def add_message(self, message: MessageRecv) -> None: async def add_message(self, message: MessageRecv) -> None:
"""根据VIP状态和中断逻辑将消息放入相应队列。""" """根据VIP状态和中断逻辑将消息放入相应队列。"""
is_vip = self._is_vip(message) is_vip = self._is_vip(message)
# 优先级分数越高,优先级越高。 new_priority = self._get_message_priority(message)
new_priority_score = self._calculate_base_priority_score(message)
should_interrupt = False should_interrupt = False
if self._current_generation_task and not self._current_generation_task.done(): if self._current_generation_task and not self._current_generation_task.done():
if self._current_message_being_replied: if self._current_message_being_replied:
current_queue, current_priority_score, _, current_msg = self._current_message_being_replied current_queue, current_priority, _, current_msg = self._current_message_being_replied
# 规则VIP从不被打断 # 规则VIP从不被打断
if current_queue == "vip": if current_queue == "vip":
@@ -234,7 +228,9 @@ class S4UChat:
if should_interrupt: if should_interrupt:
if self.gpt.partial_response: if self.gpt.partial_response:
logger.warning(f"[{self.stream_name}] Interrupting reply. Already generated: '{self.gpt.partial_response}'") logger.warning(
f"[{self.stream_name}] Interrupting reply. Already generated: '{self.gpt.partial_response}'"
)
self._current_generation_task.cancel() self._current_generation_task.cancel()
# asyncio.PriorityQueue 是最小堆,所以我们存入分数的相反数 # asyncio.PriorityQueue 是最小堆,所以我们存入分数的相反数
@@ -276,7 +272,9 @@ class S4UChat:
priority = -neg_priority priority = -neg_priority
# 检查普通消息是否超时 # 检查普通消息是否超时
if time.time() - timestamp > self._MESSAGE_TIMEOUT_SECONDS: if time.time() - timestamp > self._MESSAGE_TIMEOUT_SECONDS:
logger.info(f"[{self.stream_name}] Discarding stale normal message: {message.processed_plain_text[:20]}...") logger.info(
f"[{self.stream_name}] Discarding stale normal message: {message.processed_plain_text[:20]}..."
)
self._normal_queue.task_done() self._normal_queue.task_done()
continue # 处理下一条 continue # 处理下一条
queue_name = "normal" queue_name = "normal"
@@ -289,7 +287,9 @@ class S4UChat:
try: try:
await self._current_generation_task await self._current_generation_task
except asyncio.CancelledError: except asyncio.CancelledError:
logger.info(f"[{self.stream_name}] Reply generation was interrupted externally for {queue_name} message. The message will be discarded.") logger.info(
f"[{self.stream_name}] Reply generation was interrupted externally for {queue_name} message. The message will be discarded."
)
# 被中断的消息应该被丢弃,而不是重新排队,以响应最新的用户输入。 # 被中断的消息应该被丢弃,而不是重新排队,以响应最新的用户输入。
# 旧的重新入队逻辑会导致所有中断的消息最终都被回复。 # 旧的重新入队逻辑会导致所有中断的消息最终都被回复。
@@ -299,7 +299,7 @@ class S4UChat:
self._current_generation_task = None self._current_generation_task = None
self._current_message_being_replied = None self._current_message_being_replied = None
# 标记任务完成 # 标记任务完成
if queue_name == 'vip': if queue_name == "vip":
self._vip_queue.task_done() self._vip_queue.task_done()
else: else:
self._normal_queue.task_done() self._normal_queue.task_done()

View File

@@ -104,7 +104,9 @@ class PromptBuilder:
) )
relation_info = "".join(relation_info_list) relation_info = "".join(relation_info_list)
if relation_info: if relation_info:
relation_prompt = await global_prompt_manager.format_prompt("relation_prompt", relation_info=relation_info) relation_prompt = await global_prompt_manager.format_prompt(
"relation_prompt", relation_info=relation_info
)
return relation_prompt return relation_prompt
async def build_memory_block(self, text: str) -> str: async def build_memory_block(self, text: str) -> str:
@@ -198,7 +200,6 @@ class PromptBuilder:
return core_msg_str, background_dialogue_prompt return core_msg_str, background_dialogue_prompt
async def build_prompt_normal( async def build_prompt_normal(
self, self,
message, message,
@@ -206,11 +207,8 @@ class PromptBuilder:
message_txt: str, message_txt: str,
sender_name: str = "某人", sender_name: str = "某人",
) -> str: ) -> str:
identity_block, relation_info_block, memory_block = await asyncio.gather( identity_block, relation_info_block, memory_block = await asyncio.gather(
self.build_identity_block(), self.build_identity_block(), self.build_relation_info(chat_stream), self.build_memory_block(message_txt)
self.build_relation_info(chat_stream),
self.build_memory_block(message_txt)
) )
core_dialogue_prompt, background_dialogue_prompt = self.build_chat_history_prompts(chat_stream, message) core_dialogue_prompt, background_dialogue_prompt = self.build_chat_history_prompts(chat_stream, message)