diff --git a/CHANGELOG.md b/CHANGELOG.md index 8444d15..2d13bd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## [1.0.8] - 2026-04-17 + +### Fixed +- **LLM 工具发送状态误判**: 修复帮他人打卡时“日历已发送但工具返回失败”的问题 + - `deer_self` / `deer_other` / `retro_deer` / `get_user_deer_data` 的日历发送改为非致命流程 + - 消息发送异常不再中断工具主结果(打卡业务成功不被翻转为失败) +- **海外环境回执超时误报**: 识别 `retcode=1200` / `timeout` 为“可能已送达”的 ACK 超时场景 + - 超时场景降级为 info 日志,避免误报为真实发送失败 + - 工具结果增加 `delivery_warning` / `delivery_error` 字段用于可观测性 + ## [1.0.7] - 2026-04-03 ### Fixed diff --git a/main.py b/main.py index 40aeb8a..13e1d32 100644 --- a/main.py +++ b/main.py @@ -117,6 +117,41 @@ def _unregister_llm_tools(self): except Exception as e: logger.error(f"[DeerPipe] 移除LLM工具失败: {e}") + @staticmethod + def _append_delivery_warning( + result: dict, warning_code: str, exc: Exception + ) -> None: + result["delivery_warning"] = warning_code + result["delivery_error"] = str(exc) + + @staticmethod + def _is_send_ack_timeout(exc: Exception) -> bool: + msg = str(exc).lower() + return "retcode=1200" in msg or "timeout" in msg + + async def _send_calendar_non_fatal( + self, + event: AstrMessageEvent, + cal_result: str, + is_text: bool, + result: dict, + tool_name: str, + ) -> None: + try: + if is_text: + await event.send(event.plain_result(cal_result)) + else: + await event.send(event.image_result(cal_result)) + except Exception as exc: + if self._is_send_ack_timeout(exc): + logger.info(f"[DeerPipe] {tool_name} calendar send ack timeout: {exc}") + self._append_delivery_warning( + result, "SEND_ACK_TIMEOUT_MAY_DELIVERED", exc + ) + return + logger.warning(f"[DeerPipe] {tool_name} calendar send failed: {exc}") + self._append_delivery_warning(result, "CALENDAR_SEND_FAILED", exc) + # ================================================================== # LLM Tools - AI工具函数 (精简版) # ================================================================== @@ -135,10 +170,9 @@ async def tool_deer_self(self, event: AstrMessageEvent) -> str: async for cal_result, is_text in self.service.render_calendar( event, dt.date.today(), self.html_render, user_id=user_id ): - if is_text: - await event.send(event.plain_result(cal_result)) - else: - await event.send(event.image_result(cal_result)) + await self._send_calendar_non_fatal( + event, cal_result, is_text, result, "deer_self" + ) return json.dumps(result, ensure_ascii=False) @@ -171,10 +205,9 @@ async def tool_deer_other( async for cal_result, is_text in self.service.render_calendar( event, dt.date.today(), self.html_render, user_id=display_user_id ): - if is_text: - await event.send(event.plain_result(cal_result)) - else: - await event.send(event.image_result(cal_result)) + await self._send_calendar_non_fatal( + event, cal_result, is_text, result, "deer_other" + ) return json.dumps(result, ensure_ascii=False) @@ -209,10 +242,9 @@ async def tool_retro_deer( async for cal_result, is_text in self.service.render_calendar( event, dt.date.today(), self.html_render, user_id=user_id ): - if is_text: - await event.send(event.plain_result(cal_result)) - else: - await event.send(event.image_result(cal_result)) + await self._send_calendar_non_fatal( + event, cal_result, is_text, result, "retro_deer" + ) return json.dumps(result, ensure_ascii=False) @@ -281,10 +313,9 @@ async def tool_get_user_deer_data( async for cal_result, is_text in self.service.render_calendar( event, target_date, self.html_render, user_id=user_id ): - if is_text: - await event.send(event.plain_result(cal_result)) - else: - await event.send(event.image_result(cal_result)) + await self._send_calendar_non_fatal( + event, cal_result, is_text, result, "get_user_deer_data" + ) except ValueError as exc: logger.warning( f"Invalid date parameters: year_val={year_val}, month_val={month_val}, exc={exc}" diff --git a/metadata.yaml b/metadata.yaml index 89648c4..600fd49 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -1,6 +1,6 @@ name: astrbot_plugin_deerpipe display_name: 鹿乃子月历 -version: v1.0.7 +version: v1.0.8 author: FlanChanXwO desc: 一款可爱的每日打卡插件,记录你的健康生活每一天,生成精美的月度打卡日历,支持补签和好友互动。 repo: https://github.com/FlanChanXwO/astrbot_plugin_deerpipe