From d6ede3e6cd733312694a5521d6345c2803a5ab86 Mon Sep 17 00:00:00 2001 From: passthem Date: Fri, 21 Nov 2025 16:56:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=87=E5=87=86=E5=8C=96=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E7=9A=84=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- konabot/plugins/simple_notify/ask_llm.py | 38 +++++++++++++++++++----- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/konabot/plugins/simple_notify/ask_llm.py b/konabot/plugins/simple_notify/ask_llm.py index baa4c1e..7c80689 100644 --- a/konabot/plugins/simple_notify/ask_llm.py +++ b/konabot/plugins/simple_notify/ask_llm.py @@ -32,7 +32,7 @@ SYSTEM_PROMPT = """你是一个专门解析提醒请求的助手。请分析用 时间格式要求: - datetime: "YYYY-MM-DDTHH:MM:SS" (ISO 8601) -- datetime_delta: "PTxHxMxS" 格式 (如"PT1H30M"表示1小时30分钟) +- datetime_delta: "PxYxMxDTxHxMxS" 格式 (如"PT1H30M"表示1小时30分钟,"P3DT4H"表示三天四小时,"P5MT2M"表示五个月两分钟) 判断标准: - is_notice=true: 明确包含时间+提醒内容的请求 @@ -50,7 +50,7 @@ SYSTEM_PROMPT = """你是一个专门解析提醒请求的助手。请分析用 输出:{"datetime": null, "datetime_delta": "PT5M", "datetime_delta_minus": true, "content": "关火", "is_notice": true} 用户:"昨天提醒我关火" -输出:{"datetime": null, "datetime_delta": "PT1D", "datetime_delta_minus": true, "content": "关火", "is_notice": true} +输出:{"datetime": null, "datetime_delta": "P1D", "datetime_delta_minus": true, "content": "关火", "is_notice": true} 用户:"什么是提醒功能?" 输出:{"datetime": null, "datetime_delta": null, "datetime_delta_minus": false, "content": "", "is_notice": false} @@ -58,12 +58,13 @@ SYSTEM_PROMPT = """你是一个专门解析提醒请求的助手。请分析用 请严格按照上述格式输出JSON,不要添加任何其他文字说明。现在是 DATETIME""" pt_pattern = re.compile( - r"^PT" + r"^P" r"((?P\d+)Y)?" + r"((?P\d+)M)?" r"((?P\d+)D)?" - r"((?P\d+)H)?" + r"(T((?P\d+)H)?" r"((?P\d+)M)?" - r"((?P\d+)S)?$" + r"((?P\d+)S)?)?$" ) @@ -96,6 +97,7 @@ async def ask_ai(expression: str, now: datetime.datetime | None = None) -> tuple datetime_absolute = data.get("datetime", None) datetime_delta = data.get("datetime_delta", None) + is_minus = data.get("datetime_delta_minus", False) content = data.get("content", "") is_notice = data.get("is_notice", False) @@ -103,19 +105,41 @@ async def ask_ai(expression: str, now: datetime.datetime | None = None) -> tuple return (None, "") if datetime_absolute: try: - return (datetime.datetime.strptime(datetime_absolute, "%Y-%m-%dT%H:%M:%S"), content) + res = datetime.datetime.strptime(datetime_absolute, "%Y-%m-%dT%H:%M:%S"), content + logger.info(f"提醒功能:使用绝对时间解析 AI 返回值 raw={result} target={res[0]}") + return res except ValueError: pass if datetime_delta and (match := pt_pattern.match(datetime_delta)): years = tryint(match.group("year")) + months = tryint(match.group("month")) days = tryint(match.group("day")) hours = tryint(match.group("hour")) minutes = tryint(match.group("minute")) seconds = tryint(match.group("second")) dt = datetime.timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds) - now2 = now.replace(year=now.year + years) + if is_minus: + dt = -dt + if is_minus: + now2 = now.replace(year=now.year - years) + m = now2.month + if (months - m) >= 0: + neg_months = -(m - months - 1) + neg_years = (neg_months + 11) // 12 + target_month = 12 - ((neg_months - 1) % 12) + now2 = now2.replace(year=now2.year - neg_years, month=target_month) + else: + now2 = now2.replace(month=m - months) + else: + now2 = now.replace(year=now.year + years) + m = now2.month + now2 = now2.replace( + year=now2.year + (m + months - 1) // 12, + month=(m + months - 1) % 12 + 1 + ) + logger.info(f"提醒功能:使用相对时间解析 AI 返回值 raw={result} target={now2+dt}") return (now2 + dt, content) logger.warning(f"提醒功能:解析 AI 返回值时没有找到解析方法 raw={result}")