fix:修正s4u的一些问题,修复表达方式共享失效的问题

This commit is contained in:
SengokuCola
2025-07-17 00:55:48 +08:00
parent 45aeb2df3d
commit c12975bfdf
11 changed files with 213 additions and 83 deletions

View File

@@ -34,6 +34,10 @@ class MessageSenderContainer:
self._paused_event = asyncio.Event()
self._paused_event.set() # 默认设置为非暂停状态
self.msg_id = ""
self.voice_done = ""
async def add_message(self, chunk: str):
"""向队列中添加一个消息块。"""
@@ -84,14 +88,9 @@ class MessageSenderContainer:
delay = s4u_config.typing_delay
await asyncio.sleep(delay)
current_time = time.time()
msg_id = f"{current_time}_{random.randint(1000, 9999)}"
text_to_send = chunk
message_segment = Seg(type="text", data=text_to_send)
message_segment = Seg(type="tts_text", data=f"{self.msg_id}:{chunk}")
bot_message = MessageSending(
message_id=msg_id,
message_id=self.msg_id,
chat_stream=self.chat_stream,
bot_user_info=UserInfo(
user_id=global_config.bot.qq_account,
@@ -109,8 +108,26 @@ class MessageSenderContainer:
await bot_message.process()
await get_global_api().send_message(bot_message)
logger.info(f"已将消息 '{text_to_send}' 发往平台 '{bot_message.message_info.platform}'")
logger.info(f"已将消息 '{self.msg_id}:{chunk}' 发往平台 '{bot_message.message_info.platform}'")
message_segment = Seg(type="text", data=chunk)
bot_message = MessageSending(
message_id=self.msg_id,
chat_stream=self.chat_stream,
bot_user_info=UserInfo(
user_id=global_config.bot.qq_account,
user_nickname=global_config.bot.nickname,
platform=self.original_message.message_info.platform,
),
sender_info=self.original_message.message_info.user_info,
message_segment=message_segment,
reply=self.original_message,
is_emoji=False,
apply_set_reply_logic=True,
reply_to=f"{self.original_message.message_info.user_info.platform}:{self.original_message.message_info.user_info.user_id}",
)
await bot_message.process()
await self.storage.store_message(bot_message, self.chat_stream)
except Exception as e:
@@ -175,6 +192,10 @@ class S4UChat:
self.gpt = S4UStreamGenerator()
self.interest_dict: Dict[str, float] = {} # 用户兴趣分
self.msg_id = ""
self.voice_done = ""
logger.info(f"[{self.stream_name}] S4UChat with two-queue system initialized.")
def _get_priority_info(self, message: MessageRecv) -> dict:
@@ -197,8 +218,11 @@ class S4UChat:
def _get_interest_score(self, user_id: str) -> float:
"""获取用户的兴趣分默认为1.0"""
return self.interest_dict.get(user_id, 1.0)
def go_processing(self):
if self.voice_done == self.msg_id:
return True
return False
def _calculate_base_priority_score(self, message: MessageRecv, priority_info: dict) -> float:
"""
@@ -413,45 +437,59 @@ class S4UChat:
await asyncio.sleep(random_delay)
chat_watching = watching_manager.get_watching_by_chat_id(self.stream_id)
await chat_watching.on_message_received()
def get_processing_message_id(self):
self.msg_id = f"{time.time()}_{random.randint(1000, 9999)}"
async def _generate_and_send(self, message: MessageRecv):
"""为单个消息生成文本回复。整个过程可以被中断。"""
self._is_replying = True
total_chars_sent = 0 # 跟踪发送的总字符数
self.get_processing_message_id()
if s4u_config.enable_loading_indicator:
await send_loading(self.stream_id, "......")
await send_loading(self.stream_id, ".........")
# 视线管理:开始生成回复时切换视线状态
chat_watching = watching_manager.get_watching_by_chat_id(self.stream_id)
asyncio.create_task(self.delay_change_watching_state())
sender_container = MessageSenderContainer(self.chat_stream, message)
sender_container.start()
try:
logger.info(f"[S4U] 开始为消息生成文本和音频流: '{message.processed_plain_text[:30]}...'")
# 1. 逐句生成文本、发送
gen = self.gpt.generate_response(message, "")
async for chunk in gen:
# 如果任务被取消await 会在此处引发 CancelledError
# a. 发送文本块
await sender_container.add_message(chunk)
total_chars_sent += len(chunk) # 累计字符数
if s4u_config.enable_streaming_output:
# 流式输出,边生成边发送
gen = self.gpt.generate_response(message, "")
async for chunk in gen:
sender_container.msg_id = self.msg_id
await sender_container.add_message(chunk)
total_chars_sent += len(chunk)
else:
# 一次性输出先收集所有chunk
all_chunks = []
gen = self.gpt.generate_response(message, "")
async for chunk in gen:
all_chunks.append(chunk)
total_chars_sent += len(chunk)
# 一次性发送
sender_container.msg_id = self.msg_id
await sender_container.add_message("".join(all_chunks))
# 等待所有文本消息发送完成
await sender_container.close()
await sender_container.join()
# 回复完成后延迟每个字延迟0.4秒
if total_chars_sent > 0:
delay_time = total_chars_sent * 0.4
logger.info(f"[{self.stream_name}] 回复完成,共发送 {total_chars_sent} 个字符,等待 {delay_time:.1f} 秒后继续处理下一个消息")
await asyncio.sleep(delay_time)
start_time = time.time()
while not self.go_processing():
if time.time() - start_time > 60:
logger.warning(f"[{self.stream_name}] 等待消息发送超时60秒强制跳出循环")
break
logger.info(f"[{self.stream_name}] 等待消息发送完成...")
await asyncio.sleep(0.3)
logger.info(f"[{self.stream_name}] 所有文本块处理完毕。")