rafafawfa

This commit is contained in:
SengokuCola
2025-04-25 23:47:19 +08:00
parent 711405913e
commit 9a81979f67
2 changed files with 41 additions and 51 deletions

View File

@@ -5,7 +5,7 @@ import random # <-- 添加导入
from typing import List, Optional, Dict, Any, Deque from typing import List, Optional, Dict, Any, Deque
from collections import deque from collections import deque
from src.plugins.chat.message import MessageRecv, BaseMessageInfo, MessageThinking, MessageSending from src.plugins.chat.message import MessageRecv, BaseMessageInfo, MessageThinking, MessageSending
from src.plugins.chat.message import MessageSet, Seg # Local import needed after move from src.plugins.chat.message import Seg # Local import needed after move
from src.plugins.chat.chat_stream import ChatStream from src.plugins.chat.chat_stream import ChatStream
from src.plugins.chat.message import UserInfo from src.plugins.chat.message import UserInfo
from src.plugins.chat.chat_stream import chat_manager from src.plugins.chat.chat_stream import chat_manager
@@ -810,9 +810,7 @@ class HeartFChatting:
# 它需要负责创建 MessageThinking 和 MessageSending 对象 # 它需要负责创建 MessageThinking 和 MessageSending 对象
# 并调用 self.sender.register_thinking 和 self.sender.type_and_send_message # 并调用 self.sender.register_thinking 和 self.sender.type_and_send_message
first_bot_msg = await self._send_response_messages( first_bot_msg = await self._send_response_messages(
anchor_message=anchor_message, anchor_message=anchor_message, response_set=response_set, thinking_id=thinking_id
response_set=response_set,
thinking_id=thinking_id
) )
if first_bot_msg: if first_bot_msg:
@@ -824,7 +822,9 @@ class HeartFChatting:
await self._handle_emoji(emoji_anchor, response_set, send_emoji) await self._handle_emoji(emoji_anchor, response_set, send_emoji)
else: else:
# 如果 _send_response_messages 返回 None表示在发送前就失败或没有消息可发送 # 如果 _send_response_messages 返回 None表示在发送前就失败或没有消息可发送
logger.warning(f"{self.log_prefix}[Sender-{thinking_id}] 未能发送任何回复消息 (_send_response_messages 返回 None)。") logger.warning(
f"{self.log_prefix}[Sender-{thinking_id}] 未能发送任何回复消息 (_send_response_messages 返回 None)。"
)
# 这里可能不需要抛出异常,取决于 _send_response_messages 的具体实现 # 这里可能不需要抛出异常,取决于 _send_response_messages 的具体实现
except Exception as e: except Exception as e:
@@ -979,7 +979,7 @@ class HeartFChatting:
chat = anchor_message.chat_stream chat = anchor_message.chat_stream
chat_id = chat.stream_id chat_id = chat.stream_id
stream_name = chat_manager.get_stream_name(chat_id) or chat_id # 获取流名称用于日志 stream_name = chat_manager.get_stream_name(chat_id) or chat_id # 获取流名称用于日志
# 检查思考过程是否仍在进行,并获取开始时间 # 检查思考过程是否仍在进行,并获取开始时间
thinking_start_time = await self.heart_fc_sender.get_thinking_start_time(chat_id, thinking_id) thinking_start_time = await self.heart_fc_sender.get_thinking_start_time(chat_id, thinking_id)
@@ -1015,21 +1015,22 @@ class HeartFChatting:
reply=anchor_message, # 回复原始锚点 reply=anchor_message, # 回复原始锚点
is_head=not mark_head, is_head=not mark_head,
is_emoji=False, is_emoji=False,
thinking_start_time=thinking_start_time, # 传递原始思考开始时间 thinking_start_time=thinking_start_time, # 传递原始思考开始时间
) )
try: try:
if not mark_head: if not mark_head:
mark_head = True mark_head = True
first_bot_msg = bot_message # 保存第一个成功发送的消息对象 first_bot_msg = bot_message # 保存第一个成功发送的消息对象
await self.heart_fc_sender.type_and_send_message(bot_message, type = False) await self.heart_fc_sender.type_and_send_message(bot_message, type=False)
else: else:
await self.heart_fc_sender.type_and_send_message(bot_message, type = True) await self.heart_fc_sender.type_and_send_message(bot_message, type=True)
reply_message_ids.append(part_message_id) # 记录我们生成的ID reply_message_ids.append(part_message_id) # 记录我们生成的ID
except Exception as e: except Exception as e:
logger.error(f"{self.log_prefix}[Sender-{thinking_id}] 发送回复片段 {i} ({part_message_id}) 时失败: {e}") logger.error(
f"{self.log_prefix}[Sender-{thinking_id}] 发送回复片段 {i} ({part_message_id}) 时失败: {e}"
)
# 这里可以选择是继续发送下一个片段还是中止 # 这里可以选择是继续发送下一个片段还是中止
# 在尝试发送完所有片段后,完成原始的 thinking_id 状态 # 在尝试发送完所有片段后,完成原始的 thinking_id 状态
@@ -1039,13 +1040,12 @@ class HeartFChatting:
logger.error(f"{self.log_prefix}[Sender-{thinking_id}] 完成思考状态 {thinking_id} 时出错: {e}") logger.error(f"{self.log_prefix}[Sender-{thinking_id}] 完成思考状态 {thinking_id} 时出错: {e}")
self._current_cycle.set_response_info( self._current_cycle.set_response_info(
response_text=response_set, # 保留原始文本 response_text=response_set, # 保留原始文本
anchor_message_id=anchor_message.message_info.message_id, # 保留锚点ID anchor_message_id=anchor_message.message_info.message_id, # 保留锚点ID
reply_message_ids=reply_message_ids # 添加实际发送的ID列表 reply_message_ids=reply_message_ids, # 添加实际发送的ID列表
) )
return first_bot_msg # 返回第一个成功发送的消息对象
return first_bot_msg # 返回第一个成功发送的消息对象
async def _handle_emoji(self, anchor_message: Optional[MessageRecv], response_set: List[str], send_emoji: str = ""): async def _handle_emoji(self, anchor_message: Optional[MessageRecv], response_set: List[str], send_emoji: str = ""):
"""处理表情包 (尝试锚定到 anchor_message),使用 HeartFCSender""" """处理表情包 (尝试锚定到 anchor_message),使用 HeartFCSender"""
@@ -1060,9 +1060,8 @@ class HeartFChatting:
if emoji_raw: if emoji_raw:
emoji_path, description = emoji_raw emoji_path, description = emoji_raw
emoji_cq = image_path_to_base64(emoji_path) emoji_cq = image_path_to_base64(emoji_path)
thinking_time_point = round(time.time(), 2) # 用于唯一ID thinking_time_point = round(time.time(), 2) # 用于唯一ID
message_segment = Seg(type="emoji", data=emoji_cq) message_segment = Seg(type="emoji", data=emoji_cq)
bot_user_info = UserInfo( bot_user_info = UserInfo(
user_id=global_config.BOT_QQ, user_id=global_config.BOT_QQ,
@@ -1076,7 +1075,7 @@ class HeartFChatting:
sender_info=anchor_message.message_info.user_info, sender_info=anchor_message.message_info.user_info,
message_segment=message_segment, message_segment=message_segment,
reply=anchor_message, # 回复原始锚点 reply=anchor_message, # 回复原始锚点
is_head=False, # 表情通常不是头部消息 is_head=False, # 表情通常不是头部消息
is_emoji=True, is_emoji=True,
# 不需要 thinking_start_time # 不需要 thinking_start_time
) )
@@ -1086,7 +1085,6 @@ class HeartFChatting:
except Exception as e: except Exception as e:
logger.error(f"{self.log_prefix} 发送表情包 {bot_message.message_info.message_id} 时失败: {e}") logger.error(f"{self.log_prefix} 发送表情包 {bot_message.message_info.message_id} 时失败: {e}")
def get_cycle_history(self, last_n: Optional[int] = None) -> List[Dict[str, Any]]: def get_cycle_history(self, last_n: Optional[int] = None) -> List[Dict[str, Any]]:
"""获取循环历史记录 """获取循环历史记录

View File

@@ -1,13 +1,12 @@
# src/plugins/heartFC_chat/heartFC_sender.py # src/plugins/heartFC_chat/heartFC_sender.py
import asyncio # 重新导入 asyncio import asyncio # 重新导入 asyncio
import time from typing import Dict, Optional # 重新导入类型
from typing import Dict, List, Optional, Union # 重新导入类型
from src.common.logger import get_module_logger from src.common.logger import get_module_logger
from ..message.api import global_api from ..message.api import global_api
from ..chat.message import MessageSending, MessageThinking # 只保留 MessageSending 和 MessageThinking from ..chat.message import MessageSending, MessageThinking # 只保留 MessageSending 和 MessageThinking
from ..storage.storage import MessageStorage from ..storage.storage import MessageStorage
from ..chat.utils import truncate_message from ..chat.utils import truncate_message
from src.common.logger import LogConfig, SENDER_STYLE_CONFIG from src.common.logger import LogConfig, SENDER_STYLE_CONFIG
from src.plugins.chat.utils import calculate_typing_time from src.plugins.chat.utils import calculate_typing_time
@@ -28,17 +27,17 @@ class HeartFCSender:
self.storage = MessageStorage() self.storage = MessageStorage()
# 用于存储活跃的思考消息 # 用于存储活跃的思考消息
self.thinking_messages: Dict[str, Dict[str, MessageThinking]] = {} self.thinking_messages: Dict[str, Dict[str, MessageThinking]] = {}
self._thinking_lock = asyncio.Lock() # 保护 thinking_messages 的锁 self._thinking_lock = asyncio.Lock() # 保护 thinking_messages 的锁
async def send_message(self, message: MessageSending) -> None: async def send_message(self, message: MessageSending) -> None:
"""合并后的消息发送函数包含WS发送和日志记录""" """合并后的消息发送函数包含WS发送和日志记录"""
message_preview = truncate_message(message.processed_plain_text) message_preview = truncate_message(message.processed_plain_text)
try: try:
# 直接调用API发送消息 # 直接调用API发送消息
await global_api.send_message(message) await global_api.send_message(message)
logger.success(f"发送消息 '{message_preview}' 成功") logger.success(f"发送消息 '{message_preview}' 成功")
except Exception as e: except Exception as e:
logger.error(f"发送消息 '{message_preview}' 失败: {str(e)}") logger.error(f"发送消息 '{message_preview}' 失败: {str(e)}")
if not message.message_info.platform: if not message.message_info.platform:
@@ -82,7 +81,7 @@ class HeartFCSender:
thinking_message = self.thinking_messages.get(chat_id, {}).get(message_id) thinking_message = self.thinking_messages.get(chat_id, {}).get(message_id)
return thinking_message.thinking_start_time if thinking_message else None return thinking_message.thinking_start_time if thinking_message else None
async def type_and_send_message(self, message: MessageSending, type = False): async def type_and_send_message(self, message: MessageSending, type=False):
""" """
立即处理、发送并存储单个 MessageSending 消息。 立即处理、发送并存储单个 MessageSending 消息。
调用此方法前,应先调用 register_thinking 注册对应的思考消息。 调用此方法前,应先调用 register_thinking 注册对应的思考消息。
@@ -102,17 +101,13 @@ class HeartFCSender:
_ = message.update_thinking_time() _ = message.update_thinking_time()
# --- 条件应用 set_reply 逻辑 --- # --- 条件应用 set_reply 逻辑 ---
if ( if message.apply_set_reply_logic and message.is_head and not message.is_private_message():
message.apply_set_reply_logic
and message.is_head
and not message.is_private_message()
):
logger.debug(f"[{chat_id}] 应用 set_reply 逻辑: {message.processed_plain_text[:20]}...") logger.debug(f"[{chat_id}] 应用 set_reply 逻辑: {message.processed_plain_text[:20]}...")
message.set_reply() message.set_reply()
# --- 结束条件 set_reply --- # --- 结束条件 set_reply ---
await message.process() await message.process()
if type: if type:
typing_time = calculate_typing_time( typing_time = calculate_typing_time(
input_string=message.processed_plain_text, input_string=message.processed_plain_text,
@@ -120,15 +115,12 @@ class HeartFCSender:
is_emoji=message.is_emoji, is_emoji=message.is_emoji,
) )
await asyncio.sleep(typing_time) await asyncio.sleep(typing_time)
await self.send_message(message) await self.send_message(message)
await self.storage.store_message(message, message.chat_stream) await self.storage.store_message(message, message.chat_stream)
except Exception as e: except Exception as e:
logger.error( logger.error(f"[{chat_id}] 处理或存储消息 {message_id} 时出错: {e}")
f"[{chat_id}] 处理或存储消息 {message_id} 时出错: {e}"
)
raise e raise e
finally: finally:
await self.complete_thinking(chat_id, message_id) await self.complete_thinking(chat_id, message_id)
@@ -139,23 +131,23 @@ class HeartFCSender:
logger.error(f"[{message.message_info.platform or 'UnknownPlatform'}] 消息缺少 chat_stream无法发送") logger.error(f"[{message.message_info.platform or 'UnknownPlatform'}] 消息缺少 chat_stream无法发送")
return return
if not message.message_info or not message.message_info.message_id: if not message.message_info or not message.message_info.message_id:
logger.error(f"[{message.chat_stream.stream_id if message.chat_stream else 'UnknownStream'}] 消息缺少 message_info 或 message_id无法发送") logger.error(
f"[{message.chat_stream.stream_id if message.chat_stream else 'UnknownStream'}] 消息缺少 message_info 或 message_id无法发送"
)
return return
chat_id = message.chat_stream.stream_id chat_id = message.chat_stream.stream_id
message_id = message.message_info.message_id # 获取消息ID用于日志 message_id = message.message_info.message_id # 获取消息ID用于日志
try: try:
await message.process() await message.process()
await asyncio.sleep(0.5) await asyncio.sleep(0.5)
await self.send_message(message) # 使用现有的发送方法 await self.send_message(message) # 使用现有的发送方法
await self.storage.store_message(message, message.chat_stream) # 使用现有的存储方法 await self.storage.store_message(message, message.chat_stream) # 使用现有的存储方法
except Exception as e: except Exception as e:
logger.error( logger.error(f"[{chat_id}] 处理或存储消息 {message_id} 时出错: {e}")
f"[{chat_id}] 处理或存储消息 {message_id} 时出错: {e}"
)
# 重新抛出异常,让调用者知道失败了 # 重新抛出异常,让调用者知道失败了
raise e raise e