feat:补 tool_message,补图片场景 need_ai_reply 回传,修图片描述写 history 的 chat_id
This commit is contained in:
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user