From 11e37a157d9e5a1f2fce983b6f5d87b9f610e75e Mon Sep 17 00:00:00 2001 From: taylorxie Date: Mon, 9 Mar 2026 23:21:30 +0800 Subject: [PATCH] add --- maubot_llmplus/aibot.py | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/maubot_llmplus/aibot.py b/maubot_llmplus/aibot.py index 3cf4b5e..88bf237 100644 --- a/maubot_llmplus/aibot.py +++ b/maubot_llmplus/aibot.py @@ -159,16 +159,19 @@ class AiBotPlugin(AbsExtraConfigPlugin): msgtype=MessageType.TEXT, body="▌", format=Format.HTML, formatted_body="▌" ) response_event_id = await evt.respond(placeholder, in_thread=self.config['reply_in_thread']) + self.log.debug("Streaming: placeholder sent") accumulated = "" last_edit_len = 0 - EDIT_THRESHOLD = 50 # 每积累50个字符更新一次消息 + EDIT_THRESHOLD = 100 # 每积累100个字符更新一次消息 + pending_edit: asyncio.Task = None # 追踪正在发送的编辑任务 try: async for chunk in platform.create_chat_completion_stream(self, evt): accumulated += chunk + # 只有在没有正在进行的编辑任务时才发送中间更新 if len(accumulated) - last_edit_len >= EDIT_THRESHOLD: - try: + if pending_edit is None or pending_edit.done(): display = accumulated + " ▌" new_content = TextMessageEventContent( msgtype=MessageType.TEXT, @@ -177,18 +180,28 @@ class AiBotPlugin(AbsExtraConfigPlugin): formatted_body=markdown.render(display) ) new_content.set_edit(response_event_id) - await asyncio.wait_for( - self.client.send_message(evt.room_id, new_content), - timeout=5.0 + # 使用fire-and-forget,不等待,不取消,避免mautrix内部锁死锁 + pending_edit = asyncio.ensure_future( + self.client.send_message(evt.room_id, new_content) ) last_edit_len = len(accumulated) - except Exception as edit_err: - self.log.warning(f"Streaming mid-edit failed (skipping): {edit_err}") + self.log.debug(f"Streaming: mid-edit fired, accumulated={len(accumulated)}") + else: + self.log.debug(f"Streaming: skipping mid-edit, previous still in flight, accumulated={len(accumulated)}") except Exception as e: self.log.exception(f"Streaming error: {e}") if not accumulated: accumulated = f"Streaming error: {e}" + self.log.debug(f"Streaming: loop done, total={len(accumulated)}") + + # 等待最后一个中间编辑完成(不取消,避免锁问题) + if pending_edit and not pending_edit.done(): + try: + await asyncio.wait_for(asyncio.shield(pending_edit), timeout=10.0) + except Exception: + pass + # 输出最终完整内容 if not accumulated: accumulated = "(无响应)" @@ -199,10 +212,9 @@ class AiBotPlugin(AbsExtraConfigPlugin): formatted_body=markdown.render(accumulated) ) final_content.set_edit(response_event_id) - await asyncio.wait_for( - self.client.send_message(evt.room_id, final_content), - timeout=15.0 - ) + self.log.debug("Streaming: sending final edit") + await self.client.send_message(evt.room_id, final_content) + self.log.debug("Streaming: final edit done") def get_ai_platform(self) -> Platform: use_platform = self.config.cur_platform