refactor(message-manager): 删除自适应流管理器并优化上下文加载

-从distribution_manager和message_manager中删除adaptive_stream_manager.py及其集成
-删除过时的message_recv_backup.py,因为MessageRecv已被DatabaseMessages完全替换
-在context_manager中添加异步历史初始化,以便在启动时从数据库加载消息
-优化default_generator以使用内存中的消息,而不是重复的数据库查询
-修复message.py中的回复消息段处理,以处理DatabaseMessages格式
-从chat_stream.py中删除deepcopy并改进context_manager初始化
-清理bot.py和适配器响应方法中未使用的通知处理

突破性变化:自适应流管理系统已被完全删除。所有消息处理现在都依赖于DatabaseMessages格式。上下文管理器现在在创建时从数据库异步初始化历史记录。
This commit is contained in:
Windpicker-owo
2025-10-31 20:45:25 +08:00
parent 371041c9db
commit 655b4f20c6
11 changed files with 200 additions and 1199 deletions

View File

@@ -301,67 +301,6 @@ class ChatBot:
logger.error(f"处理命令时出错: {e}")
return False, None, True # 出错时继续处理消息
async def handle_notice_message(self, message: DatabaseMessages):
"""处理notice消息
notice消息是系统事件通知如禁言、戳一戳等具有以下特点
1. 默认不触发聊天流程,只记录
2. 可通过配置开启触发聊天流程
3. 会在提示词中展示
Args:
message: DatabaseMessages 对象
Returns:
bool: True表示notice已完整处理需要存储并终止后续流程
False表示不是notice或notice需要继续处理触发聊天流程
"""
# 检查是否是notice消息
if message.is_notify:
logger.info(f"收到notice消息: {message.notice_type}")
# 根据配置决定是否触发聊天流程
if not global_config.notice.enable_notice_trigger_chat:
logger.debug("notice消息不触发聊天流程配置已关闭将存储后终止")
return True # 返回True需要在调用处存储并终止
else:
logger.debug("notice消息触发聊天流程配置已开启继续处理")
return False # 返回False继续正常流程作为普通消息处理
# 兼容旧的notice判断方式
if message.message_id == "notice":
# 为 DatabaseMessages 设置 is_notify 运行时属性
from src.chat.message_receive.message_processor import set_db_message_runtime_attr
set_db_message_runtime_attr(message, "is_notify", True)
logger.info("旧格式notice消息")
# 同样根据配置决定
if not global_config.notice.enable_notice_trigger_chat:
logger.debug("旧格式notice消息不触发聊天流程将存储后终止")
return True # 需要存储并终止
else:
logger.debug("旧格式notice消息触发聊天流程继续处理")
return False # 继续正常流程
# DatabaseMessages 不再有 message_segment适配器响应处理已在消息处理阶段完成
# 这里保留逻辑以防万一,但实际上不会再执行到
return False # 不是notice消息继续正常流程
async def handle_adapter_response(self, message: DatabaseMessages):
"""处理适配器命令响应
注意: 此方法目前未被调用,但保留以备将来使用
"""
try:
from src.plugin_system.apis.send_api import put_adapter_response
# DatabaseMessages 使用 message_segments 字段存储消息段
# 注意: 这可能需要根据实际使用情况进行调整
logger.warning("handle_adapter_response 方法被调用,但目前未实现对 DatabaseMessages 的支持")
except Exception as e:
logger.error(f"处理适配器响应时出错: {e}")
async def message_process(self, message_data: dict[str, Any]) -> None:
"""处理转化后的统一格式消息"""
try:
@@ -454,29 +393,6 @@ class ChatBot:
logger.info(f"[硬编码过滤] 检测到媒体内容处理失败({processed_text}),消息被静默处理。")
return
# 处理notice消息
# notice_handled=True: 表示notice不触发聊天需要在此存储并终止
# notice_handled=False: 表示notice触发聊天或不是notice继续正常流程
notice_handled = await self.handle_notice_message(message)
if notice_handled:
# notice消息不触发聊天流程在此进行存储和记录后终止
try:
# message 已经是 DatabaseMessages直接使用
# 添加到message_manager这会将notice添加到全局notice管理器
await message_manager.add_message(chat.stream_id, message)
logger.info(f"✅ Notice消息已添加到message_manager: type={message.notice_type}, stream={chat.stream_id}")
except Exception as e:
logger.error(f"Notice消息添加到message_manager失败: {e}", exc_info=True)
# 存储notice消息到数据库需要更新 storage.py 支持 DatabaseMessages
# 暂时跳过存储,等待更新 storage.py
logger.debug("notice消息已添加到message_manager存储功能待更新")
return
# 如果notice_handled=False则继续执行后续流程
# 对于启用触发聊天的notice会在后续的正常流程中被存储和处理
# 过滤检查
# DatabaseMessages 使用 display_message 作为原始消息表示
raw_text = message.display_message or message.processed_plain_text or ""

View File

@@ -62,36 +62,6 @@ class ChatStream:
self._focus_energy = 0.5 # 内部存储的focus_energy值
self.no_reply_consecutive = 0
def __deepcopy__(self, memo):
"""自定义深拷贝方法,避免复制不可序列化的 asyncio.Task 对象"""
import copy
# 创建新的实例
new_stream = ChatStream(
stream_id=self.stream_id,
platform=self.platform,
user_info=copy.deepcopy(self.user_info, memo),
group_info=copy.deepcopy(self.group_info, memo),
)
# 复制基本属性
new_stream.create_time = self.create_time
new_stream.last_active_time = self.last_active_time
new_stream.sleep_pressure = self.sleep_pressure
new_stream.saved = self.saved
new_stream.base_interest_energy = self.base_interest_energy
new_stream._focus_energy = self._focus_energy
new_stream.no_reply_consecutive = self.no_reply_consecutive
# 复制 context_manager包含 stream_context
new_stream.context_manager = copy.deepcopy(self.context_manager, memo)
# 清理 processing_task如果存在
if hasattr(new_stream.context_manager.context, "processing_task"):
new_stream.context_manager.context.processing_task = None
return new_stream
def to_dict(self) -> dict:
"""转换为字典格式"""
return {
@@ -461,7 +431,6 @@ class ChatManager:
# 更新用户信息和群组信息
stream.update_active_time()
stream = copy.deepcopy(stream) # 返回副本以避免外部修改影响缓存
if user_info.platform and user_info.user_id:
stream.user_info = user_info
if group_info:
@@ -530,7 +499,6 @@ class ChatManager:
logger.error(f"获取或创建聊天流失败: {e}", exc_info=True)
raise e
stream = copy.deepcopy(stream)
from src.common.data_models.database_data_model import DatabaseMessages
if stream_id in self.last_messages and isinstance(self.last_messages[stream_id], DatabaseMessages):
@@ -539,11 +507,12 @@ class ChatManager:
logger.debug(f"聊天流 {stream_id} 不在最后消息列表中,可能是新创建的")
# 确保 ChatStream 有自己的 context_manager
if not hasattr(stream, "context_manager"):
if not hasattr(stream, "context_manager") or stream.context_manager is None:
from src.chat.message_manager.context_manager import SingleStreamContextManager
from src.common.data_models.message_manager_data_model import StreamContext
from src.plugin_system.base.component_types import ChatMode, ChatType
logger.info(f"为 stream {stream_id} 创建新的 context_manager")
stream.context_manager = SingleStreamContextManager(
stream_id=stream_id,
context=StreamContext(
@@ -552,6 +521,8 @@ class ChatManager:
chat_mode=ChatMode.NORMAL,
),
)
else:
logger.info(f"stream {stream_id} 已有 context_manager跳过创建")
# 保存到内存和数据库
self.streams[stream_id] = stream
@@ -781,11 +752,12 @@ class ChatManager:
# await stream.set_context(self.last_messages[stream.stream_id])
# 确保 ChatStream 有自己的 context_manager
if not hasattr(stream, "context_manager"):
if not hasattr(stream, "context_manager") or stream.context_manager is None:
from src.chat.message_manager.context_manager import SingleStreamContextManager
from src.common.data_models.message_manager_data_model import StreamContext
from src.plugin_system.base.component_types import ChatMode, ChatType
logger.debug(f"为加载的 stream {stream.stream_id} 创建新的 context_manager")
stream.context_manager = SingleStreamContextManager(
stream_id=stream.stream_id,
context=StreamContext(
@@ -794,6 +766,8 @@ class ChatManager:
chat_mode=ChatMode.NORMAL,
),
)
else:
logger.debug(f"加载的 stream {stream.stream_id} 已有 context_manager")
except Exception as e:
logger.error(f"从数据库加载所有聊天流失败 (SQLAlchemy): {e}", exc_info=True)

View File

@@ -160,7 +160,7 @@ class MessageProcessBase(Message):
return "[表情,网卡了加载不出来]"
elif seg.type == "voice":
# 检查消息是否由机器人自己发送
# 检查消息是否由机器人自己发送
# self.message_info 来自 MessageBase指当前消息的信息
if self.message_info and self.message_info.user_info and str(self.message_info.user_info.user_id) == str(global_config.bot.qq_account):
logger.info(f"检测到机器人自身发送的语音消息 (User ID: {self.message_info.user_info.user_id}),尝试从缓存获取文本。")
if isinstance(seg.data, str):
@@ -182,10 +182,24 @@ class MessageProcessBase(Message):
return f"@{nickname}"
return f"@{seg.data}" if isinstance(seg.data, str) else "@未知用户"
elif seg.type == "reply":
if self.reply and hasattr(self.reply, "processed_plain_text"):
# print(f"self.reply.processed_plain_text: {self.reply.processed_plain_text}")
# print(f"reply: {self.reply}")
return f"[回复<{self.reply.message_info.user_info.user_nickname}({self.reply.message_info.user_info.user_id})> 的消息:{self.reply.processed_plain_text}]" # type: ignore
# 处理回复消息段
if self.reply:
# 检查 reply 对象是否有必要的属性
if hasattr(self.reply, "processed_plain_text") and self.reply.processed_plain_text:
# DatabaseMessages 使用 user_info 而不是 message_info.user_info
user_nickname = self.reply.user_info.user_nickname if self.reply.user_info else "未知用户"
user_id = self.reply.user_info.user_id if self.reply.user_info else ""
return f"[回复<{user_nickname}({user_id})> 的消息:{self.reply.processed_plain_text}]"
else:
# reply 对象存在但没有 processed_plain_text返回简化的回复标识
logger.debug(f"reply 消息段没有 processed_plain_text 属性message_id: {getattr(self.reply, 'message_id', 'unknown')}")
return "[回复消息]"
else:
# 没有 reply 对象,但有 reply 消息段(可能是机器人自己发送的消息)
# 这种情况下 seg.data 应该包含被回复消息的 message_id
if isinstance(seg.data, str):
logger.debug(f"处理 reply 消息段,但 self.reply 为 Nonereply_to message_id: {seg.data}")
return f"[回复消息 {seg.data}]"
return None
else:
return f"[{seg.type}:{seg.data!s}]"

View File

@@ -79,13 +79,9 @@ async def process_message_from_dict(message_dict: dict[str, Any], stream_id: str
group_name = group_info.group_name if group_info else None
group_platform = group_info.platform if group_info else None
# 生成 chat_id
if group_info and group_id:
chat_id = f"{platform}_{group_id}"
elif user_info and user_info.user_id:
chat_id = f"{platform}_{user_info.user_id}_private"
else:
chat_id = stream_id
# chat_id 应该直接使用 stream_id与数据库存储格式一致
# stream_id 是通过 platform + user_id/group_id 的 SHA-256 哈希生成的
chat_id = stream_id
# 准备 additional_config
additional_config_str = _prepare_additional_config(message_info, is_notify, is_public_notice, notice_type)

View File

@@ -1,434 +0,0 @@
# MessageRecv 类备份 - 已从 message.py 中移除
# 备份日期: 2025-10-31
# 此类已被 DatabaseMessages 完全取代
# MessageRecv 类已被移除
# 现在所有消息处理都使用 DatabaseMessages
# 如果需要从消息字典创建 DatabaseMessages请使用 message_processor.process_message_from_dict()
#
# 历史参考: MessageRecv 曾经是接收消息的包装类,现已被 DatabaseMessages 完全取代
# 迁移完成日期: 2025-10-31
"""
# 以下是已删除的 MessageRecv 类(保留作为参考)
class MessageRecv:
接收消息类 - DatabaseMessages 的轻量级包装器
这个类现在主要作为适配器层,处理外部消息格式并内部使用 DatabaseMessages。
保留此类是为了向后兼容性和处理 message_segment 的异步逻辑。
"""
def __init__(self, message_dict: dict[str, Any]):
"""从MessageCQ的字典初始化
Args:
message_dict: MessageCQ序列化后的字典
"""
# 保留原始消息信息用于某些场景
self.message_info = BaseMessageInfo.from_dict(message_dict.get("message_info", {}))
self.message_segment = Seg.from_dict(message_dict.get("message_segment", {}))
self.raw_message = message_dict.get("raw_message")
# 处理状态(在process()之前临时使用)
self._processing_state = {
"is_emoji": False,
"has_emoji": False,
"is_picid": False,
"has_picid": False,
"is_voice": False,
"is_video": False,
"is_mentioned": None,
"is_at": False,
"priority_mode": "interest",
"priority_info": None,
}
self.chat_stream = None
self.reply = None
self.processed_plain_text = message_dict.get("processed_plain_text", "")
# 解析additional_config中的notice信息
self.is_notify = False
self.is_public_notice = False
self.notice_type = None
if self.message_info.additional_config and isinstance(self.message_info.additional_config, dict):
self.is_notify = self.message_info.additional_config.get("is_notice", False)
self.is_public_notice = self.message_info.additional_config.get("is_public_notice", False)
self.notice_type = self.message_info.additional_config.get("notice_type")
# 兼容性属性 - 代理到 _processing_state
@property
def is_emoji(self) -> bool:
return self._processing_state["is_emoji"]
@is_emoji.setter
def is_emoji(self, value: bool):
self._processing_state["is_emoji"] = value
@property
def has_emoji(self) -> bool:
return self._processing_state["has_emoji"]
@has_emoji.setter
def has_emoji(self, value: bool):
self._processing_state["has_emoji"] = value
@property
def is_picid(self) -> bool:
return self._processing_state["is_picid"]
@is_picid.setter
def is_picid(self, value: bool):
self._processing_state["is_picid"] = value
@property
def has_picid(self) -> bool:
return self._processing_state["has_picid"]
@has_picid.setter
def has_picid(self, value: bool):
self._processing_state["has_picid"] = value
@property
def is_voice(self) -> bool:
return self._processing_state["is_voice"]
@is_voice.setter
def is_voice(self, value: bool):
self._processing_state["is_voice"] = value
@property
def is_video(self) -> bool:
return self._processing_state["is_video"]
@is_video.setter
def is_video(self, value: bool):
self._processing_state["is_video"] = value
@property
def is_mentioned(self):
return self._processing_state["is_mentioned"]
@is_mentioned.setter
def is_mentioned(self, value):
self._processing_state["is_mentioned"] = value
@property
def is_at(self) -> bool:
return self._processing_state["is_at"]
@is_at.setter
def is_at(self, value: bool):
self._processing_state["is_at"] = value
@property
def priority_mode(self) -> str:
return self._processing_state["priority_mode"]
@priority_mode.setter
def priority_mode(self, value: str):
self._processing_state["priority_mode"] = value
@property
def priority_info(self):
return self._processing_state["priority_info"]
@priority_info.setter
def priority_info(self, value):
self._processing_state["priority_info"] = value
# 其他常用属性
interest_value: float = 0.0
is_command: bool = False
memorized_times: int = 0
def __post_init__(self):
"""dataclass 初始化后处理"""
self.key_words = []
self.key_words_lite = []
def update_chat_stream(self, chat_stream: "ChatStream"):
self.chat_stream = chat_stream
def to_database_message(self) -> "DatabaseMessages":
"""将 MessageRecv 转换为 DatabaseMessages 对象
Returns:
DatabaseMessages: 数据库消息对象
"""
import time
message_info = self.message_info
msg_user_info = getattr(message_info, "user_info", None)
stream_user_info = getattr(self.chat_stream, "user_info", None) if self.chat_stream else None
group_info = getattr(self.chat_stream, "group_info", None) if self.chat_stream else None
message_id = message_info.message_id or ""
message_time = message_info.time if hasattr(message_info, "time") and message_info.time is not None else time.time()
is_mentioned = None
if isinstance(self.is_mentioned, bool):
is_mentioned = self.is_mentioned
elif isinstance(self.is_mentioned, int | float):
is_mentioned = self.is_mentioned != 0
# 提取用户信息
user_id = ""
user_nickname = ""
user_cardname = None
user_platform = ""
if msg_user_info:
user_id = str(getattr(msg_user_info, "user_id", "") or "")
user_nickname = getattr(msg_user_info, "user_nickname", "") or ""
user_cardname = getattr(msg_user_info, "user_cardname", None)
user_platform = getattr(msg_user_info, "platform", "") or ""
elif stream_user_info:
user_id = str(getattr(stream_user_info, "user_id", "") or "")
user_nickname = getattr(stream_user_info, "user_nickname", "") or ""
user_cardname = getattr(stream_user_info, "user_cardname", None)
user_platform = getattr(stream_user_info, "platform", "") or ""
# 提取聊天流信息
chat_user_id = str(getattr(stream_user_info, "user_id", "") or "") if stream_user_info else ""
chat_user_nickname = getattr(stream_user_info, "user_nickname", "") or "" if stream_user_info else ""
chat_user_cardname = getattr(stream_user_info, "user_cardname", None) if stream_user_info else None
chat_user_platform = getattr(stream_user_info, "platform", "") or "" if stream_user_info else ""
group_id = getattr(group_info, "group_id", None) if group_info else None
group_name = getattr(group_info, "group_name", None) if group_info else None
group_platform = getattr(group_info, "platform", None) if group_info else None
# 准备 additional_config
additional_config_str = None
try:
import orjson
additional_config_data = {}
# 首先获取adapter传递的additional_config
if hasattr(message_info, 'additional_config') and message_info.additional_config:
if isinstance(message_info.additional_config, dict):
additional_config_data = message_info.additional_config.copy()
elif isinstance(message_info.additional_config, str):
try:
additional_config_data = orjson.loads(message_info.additional_config)
except Exception as e:
logger.warning(f"无法解析 additional_config JSON: {e}")
additional_config_data = {}
# 添加notice相关标志
if self.is_notify:
additional_config_data["is_notice"] = True
additional_config_data["notice_type"] = self.notice_type or "unknown"
additional_config_data["is_public_notice"] = bool(self.is_public_notice)
# 添加format_info到additional_config中
if hasattr(message_info, 'format_info') and message_info.format_info:
try:
format_info_dict = message_info.format_info.to_dict()
additional_config_data["format_info"] = format_info_dict
logger.debug(f"[message.py] 嵌入 format_info 到 additional_config: {format_info_dict}")
except Exception as e:
logger.warning(f"将 format_info 转换为字典失败: {e}")
# 序列化为JSON字符串
if additional_config_data:
additional_config_str = orjson.dumps(additional_config_data).decode("utf-8")
except Exception as e:
logger.error(f"准备 additional_config 失败: {e}")
# 创建数据库消息对象
db_message = DatabaseMessages(
message_id=message_id,
time=float(message_time),
chat_id=self.chat_stream.stream_id if self.chat_stream else "",
processed_plain_text=self.processed_plain_text,
display_message=self.processed_plain_text,
is_mentioned=is_mentioned,
is_at=bool(self.is_at) if self.is_at is not None else None,
is_emoji=bool(self.is_emoji),
is_picid=bool(self.is_picid),
is_command=bool(self.is_command),
is_notify=bool(self.is_notify),
is_public_notice=bool(self.is_public_notice),
notice_type=self.notice_type,
additional_config=additional_config_str,
user_id=user_id,
user_nickname=user_nickname,
user_cardname=user_cardname,
user_platform=user_platform,
chat_info_stream_id=self.chat_stream.stream_id if self.chat_stream else "",
chat_info_platform=self.chat_stream.platform if self.chat_stream else "",
chat_info_create_time=float(self.chat_stream.create_time) if self.chat_stream else 0.0,
chat_info_last_active_time=float(self.chat_stream.last_active_time) if self.chat_stream else 0.0,
chat_info_user_id=chat_user_id,
chat_info_user_nickname=chat_user_nickname,
chat_info_user_cardname=chat_user_cardname,
chat_info_user_platform=chat_user_platform,
chat_info_group_id=group_id,
chat_info_group_name=group_name,
chat_info_group_platform=group_platform,
)
# 同步兴趣度等衍生属性
db_message.interest_value = getattr(self, "interest_value", 0.0)
setattr(db_message, "should_reply", getattr(self, "should_reply", False))
setattr(db_message, "should_act", getattr(self, "should_act", False))
return db_message
async def process(self) -> None:
"""处理消息内容,生成纯文本和详细文本
这个方法必须在创建实例后显式调用,因为它包含异步操作。
"""
self.processed_plain_text = await self._process_message_segments(self.message_segment)
async def _process_single_segment(self, segment: Seg) -> str:
"""处理单个消息段
Args:
segment: 消息段
Returns:
str: 处理后的文本
"""
try:
if segment.type == "text":
self.is_picid = False
self.is_emoji = False
self.is_video = False
return segment.data # type: ignore
elif segment.type == "at":
self.is_picid = False
self.is_emoji = False
self.is_video = False
# 处理at消息格式为"昵称:QQ号"
if isinstance(segment.data, str) and ":" in segment.data:
nickname, qq_id = segment.data.split(":", 1)
return f"@{nickname}"
return f"@{segment.data}" if isinstance(segment.data, str) else "@未知用户"
elif segment.type == "image":
# 如果是base64图片数据
if isinstance(segment.data, str):
self.has_picid = True
self.is_picid = True
self.is_emoji = False
self.is_video = False
image_manager = get_image_manager()
# print(f"segment.data: {segment.data}")
_, processed_text = await image_manager.process_image(segment.data)
return processed_text
return "[发了一张图片,网卡了加载不出来]"
elif segment.type == "emoji":
self.has_emoji = True
self.is_emoji = True
self.is_picid = False
self.is_voice = False
self.is_video = False
if isinstance(segment.data, str):
return await get_image_manager().get_emoji_description(segment.data)
return "[发了一个表情包,网卡了加载不出来]"
elif segment.type == "voice":
self.is_picid = False
self.is_emoji = False
self.is_voice = True
self.is_video = False
# 检查消息是否由机器人自己发送
if self.message_info and self.message_info.user_info and str(self.message_info.user_info.user_id) == str(global_config.bot.qq_account):
logger.info(f"检测到机器人自身发送的语音消息 (User ID: {self.message_info.user_info.user_id}),尝试从缓存获取文本。")
if isinstance(segment.data, str):
cached_text = consume_self_voice_text(segment.data)
if cached_text:
logger.info(f"成功从缓存中获取语音文本: '{cached_text[:70]}...'")
return f"[语音:{cached_text}]"
else:
logger.warning("机器人自身语音消息缓存未命中,将回退到标准语音识别。")
# 标准语音识别流程 (也作为缓存未命中的后备方案)
if isinstance(segment.data, str):
return await get_voice_text(segment.data)
return "[发了一段语音,网卡了加载不出来]"
elif segment.type == "mention_bot":
self.is_picid = False
self.is_emoji = False
self.is_voice = False
self.is_video = False
self.is_mentioned = float(segment.data) # type: ignore
return ""
elif segment.type == "priority_info":
self.is_picid = False
self.is_emoji = False
self.is_voice = False
if isinstance(segment.data, dict):
# 处理优先级信息
self.priority_mode = "priority"
self.priority_info = segment.data
"""
{
'message_type': 'vip', # vip or normal
'message_priority': 1.0, # 优先级大为优先float
}
"""
return ""
elif segment.type == "file":
if isinstance(segment.data, dict):
file_name = segment.data.get('name', '未知文件')
file_size = segment.data.get('size', '未知大小')
return f"[文件:{file_name} ({file_size}字节)]"
return "[收到一个文件]"
elif segment.type == "video":
self.is_picid = False
self.is_emoji = False
self.is_voice = False
self.is_video = True
logger.info(f"接收到视频消息,数据类型: {type(segment.data)}")
# 检查视频分析功能是否可用
if not is_video_analysis_available():
logger.warning("⚠️ Rust视频处理模块不可用跳过视频分析")
return "[视频]"
if global_config.video_analysis.enable:
logger.info("已启用视频识别,开始识别")
if isinstance(segment.data, dict):
try:
# 从Adapter接收的视频数据
video_base64 = segment.data.get("base64")
filename = segment.data.get("filename", "video.mp4")
logger.info(f"视频文件名: {filename}")
logger.info(f"Base64数据长度: {len(video_base64) if video_base64 else 0}")
if video_base64:
# 解码base64视频数据
video_bytes = base64.b64decode(video_base64)
logger.info(f"解码后视频大小: {len(video_bytes)} 字节")
# 使用video analyzer分析视频
video_analyzer = get_video_analyzer()
result = await video_analyzer.analyze_video_from_bytes(
video_bytes, filename, prompt=global_config.video_analysis.batch_analysis_prompt
)
logger.info(f"视频分析结果: {result}")
# 返回视频分析结果
summary = result.get("summary", "")
if summary:
return f"[视频内容] {summary}"
else:
return "[已收到视频,但分析失败]"
else:
logger.warning("视频消息中没有base64数据")
return "[收到视频消息,但数据异常]"
except Exception as e:
logger.error(f"视频处理失败: {e!s}")
import traceback
logger.error(f"错误详情: {traceback.format_exc()}")
return "[收到视频,但处理时出现错误]"
else:
logger.warning(f"视频消息数据不是字典格式: {type(segment.data)}")
return "[发了一个视频,但格式不支持]"
else: