feat:补 tool_message,补图片场景 need_ai_reply 回传,修图片描述写 history 的 chat_id

This commit is contained in:
2025-12-30 17:01:36 +08:00
parent dc20e580a0
commit a0977607bd

View File

@@ -2803,8 +2803,6 @@ class AIChat(PluginBase):
# 并行执行所有工具 # 并行执行所有工具
if tasks: if tasks:
results = await asyncio.gather(*tasks, return_exceptions=True) results = await asyncio.gather(*tasks, return_exceptions=True)
# 收集需要 AI 回复的工具结果
need_ai_reply_results = [] need_ai_reply_results = []
# 处理每个工具的结果 # 处理每个工具的结果
@@ -2812,6 +2810,7 @@ class AIChat(PluginBase):
tool_info = tool_info_list[i] tool_info = tool_info_list[i]
function_name = tool_info["function_name"] function_name = tool_info["function_name"]
tool_call_id = tool_info["tool_call_id"] tool_call_id = tool_info["tool_call_id"]
tool_call_id = tool_info["tool_call_id"]
if isinstance(result, Exception): if isinstance(result, Exception):
logger.error(f"[异步] 工具 {function_name} 执行异常: {result}") logger.error(f"[异步] 工具 {function_name} 执行异常: {result}")
@@ -2853,7 +2852,7 @@ class AIChat(PluginBase):
logger.warning(f"[异步] 工具 {function_name} 输出清洗后为空,已跳过发送") logger.warning(f"[异步] 工具 {function_name} 输出清洗后为空,已跳过发送")
# 工具失败默认回一条错误提示 # 工具失败默认回一条错误提示
if not tool_result.success and tool_result.message and not tool_result.no_reply: if not tool_result.success and tool_message and not tool_result.no_reply:
try: try:
if tool_message: if tool_message:
await bot.send_text(from_wxid, f"{tool_message}") await bot.send_text(from_wxid, f"{tool_message}")
@@ -3080,10 +3079,12 @@ class AIChat(PluginBase):
# 并行执行所有工具 # 并行执行所有工具
if tasks: if tasks:
results = await asyncio.gather(*tasks, return_exceptions=True) results = await asyncio.gather(*tasks, return_exceptions=True)
need_ai_reply_results = []
for i, result in enumerate(results): for i, result in enumerate(results):
tool_info = tool_info_list[i] tool_info = tool_info_list[i]
function_name = tool_info["function_name"] function_name = tool_info["function_name"]
tool_call_id = tool_info["tool_call_id"]
if isinstance(result, Exception): if isinstance(result, Exception):
logger.error(f"[异步-图片] 工具 {function_name} 执行异常: {result}") logger.error(f"[异步-图片] 工具 {function_name} 执行异常: {result}")
@@ -3097,19 +3098,29 @@ class AIChat(PluginBase):
if not tool_result: if not tool_result:
continue continue
tool_message = self._sanitize_llm_output(tool_result.message or "")
if tool_result.success: if tool_result.success:
logger.success(f"[异步-图片] 工具 {function_name} 执行成功") logger.success(f"[异步-图片] 工具 {function_name} 执行成功")
else: else:
logger.warning(f"[异步-图片] 工具 {function_name} 执行失败") logger.warning(f"[异步-图片] 工具 {function_name} 执行失败")
if tool_result.success and not tool_result.already_sent and tool_result.message and not tool_result.no_reply: if tool_result.need_ai_reply:
need_ai_reply_results.append({
"tool_call_id": tool_call_id,
"function_name": function_name,
"result": tool_message
})
continue
if tool_result.success and not tool_result.already_sent and tool_message and not tool_result.no_reply:
if tool_result.send_result_text: if tool_result.send_result_text:
if tool_message: if tool_message:
await bot.send_text(from_wxid, tool_message) await bot.send_text(from_wxid, tool_message)
else: else:
logger.warning(f"[异步-图片] 工具 {function_name} 输出清洗后为空,已跳过发送") logger.warning(f"[异步-图片] 工具 {function_name} 输出清洗后为空,已跳过发送")
if not tool_result.success and tool_result.message and not tool_result.no_reply: if not tool_result.success and tool_message and not tool_result.no_reply:
try: try:
if tool_message: if tool_message:
await bot.send_text(from_wxid, f"{tool_message}") await bot.send_text(from_wxid, f"{tool_message}")
@@ -3122,6 +3133,12 @@ class AIChat(PluginBase):
if tool_message: if tool_message:
self._add_to_memory(chat_id, "assistant", f"[工具 {function_name} 结果]: {tool_message}") self._add_to_memory(chat_id, "assistant", f"[工具 {function_name} 结果]: {tool_message}")
if need_ai_reply_results:
await self._continue_with_tool_results(
need_ai_reply_results, bot, from_wxid, chat_id,
nickname, is_group, messages, tool_calls_data
)
logger.info(f"[异步-图片] 所有工具执行完成") logger.info(f"[异步-图片] 所有工具执行完成")
except Exception as e: except Exception as e:
@@ -4635,16 +4652,17 @@ class AIChat(PluginBase):
# 获取用户昵称 - 使用缓存优化 # 获取用户昵称 - 使用缓存优化
nickname = await self._get_user_display_label(bot, from_wxid, user_wxid, is_group) nickname = await self._get_user_display_label(bot, from_wxid, user_wxid, is_group)
history_chat_id = self._get_group_history_chat_id(from_wxid, user_wxid)
# 立即插入占位符到 history # 立即插入占位符到 history
placeholder_id = str(uuid.uuid4()) placeholder_id = str(uuid.uuid4())
await self._add_to_history_with_id(from_wxid, nickname, "[图片: 处理中...]", placeholder_id) await self._add_to_history_with_id(history_chat_id, nickname, "[图片: 处理中...]", placeholder_id)
logger.info(f"已插入图片占位符: {placeholder_id}") logger.info(f"已插入图片占位符: {placeholder_id}")
# 将任务加入队列(不阻塞) # 将任务加入队列(不阻塞)
task = { task = {
"bot": bot, "bot": bot,
"from_wxid": from_wxid, "history_chat_id": history_chat_id,
"nickname": nickname, "nickname": nickname,
"cdnbigimgurl": cdnbigimgurl, "cdnbigimgurl": cdnbigimgurl,
"aeskey": aeskey, "aeskey": aeskey,
@@ -4672,7 +4690,7 @@ class AIChat(PluginBase):
try: try:
await self._generate_and_update_image_description( await self._generate_and_update_image_description(
task["bot"], task["from_wxid"], task["nickname"], task["bot"], task["history_chat_id"], task["nickname"],
task["cdnbigimgurl"], task["aeskey"], task["is_emoji"], task["cdnbigimgurl"], task["aeskey"], task["is_emoji"],
task["placeholder_id"], task["config"] task["placeholder_id"], task["config"]
) )
@@ -4686,7 +4704,7 @@ class AIChat(PluginBase):
except ValueError: except ValueError:
pass pass
async def _generate_and_update_image_description(self, bot, from_wxid: str, nickname: str, async def _generate_and_update_image_description(self, bot, history_chat_id: str, nickname: str,
cdnbigimgurl: str, aeskey: str, is_emoji: bool, cdnbigimgurl: str, aeskey: str, is_emoji: bool,
placeholder_id: str, image_desc_config: dict): placeholder_id: str, image_desc_config: dict):
"""异步生成图片描述并更新 history""" """异步生成图片描述并更新 history"""
@@ -4699,7 +4717,7 @@ class AIChat(PluginBase):
if not image_base64: if not image_base64:
logger.warning(f"{'表情包' if is_emoji else '图片'}下载失败") logger.warning(f"{'表情包' if is_emoji else '图片'}下载失败")
await self._update_history_by_id(from_wxid, placeholder_id, "[图片]") await self._update_history_by_id(history_chat_id, placeholder_id, "[图片]")
return return
# 调用 AI 生成图片描述 # 调用 AI 生成图片描述
@@ -4708,17 +4726,17 @@ class AIChat(PluginBase):
if description: if description:
cleaned_description = self._sanitize_llm_output(description) cleaned_description = self._sanitize_llm_output(description)
await self._update_history_by_id(from_wxid, placeholder_id, f"[图片: {cleaned_description}]") await self._update_history_by_id(history_chat_id, placeholder_id, f"[图片: {cleaned_description}]")
logger.success(f"已更新图片描述: {nickname} - {cleaned_description[:30]}...") logger.success(f"已更新图片描述: {nickname} - {cleaned_description[:30]}...")
else: else:
await self._update_history_by_id(from_wxid, placeholder_id, "[图片]") await self._update_history_by_id(history_chat_id, placeholder_id, "[图片]")
logger.warning(f"图片描述生成失败") logger.warning(f"图片描述生成失败")
except asyncio.CancelledError: except asyncio.CancelledError:
raise raise
except Exception as e: except Exception as e:
logger.error(f"异步生成图片描述失败: {e}") logger.error(f"异步生成图片描述失败: {e}")
await self._update_history_by_id(from_wxid, placeholder_id, "[图片]") await self._update_history_by_id(history_chat_id, placeholder_id, "[图片]")
@on_image_message(priority=15) @on_image_message(priority=15)
async def handle_image_message(self, bot, message: dict): async def handle_image_message(self, bot, message: dict):