Files
Bubbles/commands/reminder_router.py
2025-10-16 11:22:11 +08:00

79 lines
3.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
import logging
from dataclasses import dataclass
from typing import Any, Dict, Optional, Tuple
from .context import MessageContext
REMINDER_ROUTER_HISTORY_LIMIT = 10
@dataclass
class ReminderDecision:
action: str
params: str = ""
class ReminderRouter:
"""二级提醒路由器,用于在提醒场景下判定具体操作"""
def __init__(self) -> None:
self.logger = logging.getLogger(__name__ + ".ReminderRouter")
def _build_prompt(self) -> str:
return (
"你是提醒助手的路由器。根据用户关于提醒的说法,判断应该执行哪个操作,并返回 JSON。\n\n"
"### 可执行的操作:\n"
"- create创建新的提醒需要从用户话语中提取完整的提醒内容包括时间、人称、事项等\n"
"- list查询当前用户的所有提醒当用户想要查看、看看、列出、有哪些提醒时使用。\n"
"- delete删除提醒当用户想取消、删除、移除某个提醒时使用。需要根据用户给出的描述、关键字或者编号帮助定位哪条提醒。\n\n"
"### 返回格式:\n"
"{\n"
' "action": "create" | "list" | "delete",\n'
' "content": "从用户话语中提取或保留的关键信息(删除或新增时必填)"\n'
"}\n\n"
"注意:只返回 JSON不要包含多余文字。若无法识别返回 create 并把原句放进 content。"
)
def route(self, ctx: MessageContext, original_text: str) -> Optional[ReminderDecision]:
chat_model = getattr(ctx, "chat", None) or getattr(ctx.robot, "chat", None)
if not chat_model:
self.logger.error("提醒路由器:缺少可用的聊天模型。")
return None
prompt = self._build_prompt()
user_input = f"用户关于提醒的输入:{original_text}"
try:
ai_response = chat_model.get_answer(
user_input,
wxid=ctx.get_receiver(),
system_prompt_override=prompt,
specific_max_history=REMINDER_ROUTER_HISTORY_LIMIT,
)
self.logger.debug("提醒路由器原始响应: %s", ai_response)
json_match = json.loads(json_response(ai_response))
action = json_match.get("action", "").strip().lower()
content = json_match.get("content", "").strip()
if action not in {"create", "list", "delete"}:
self.logger.warning("提醒路由器:未知动作 %s,默认为 create。", action)
action = "create"
return ReminderDecision(action=action, params=content)
except Exception as exc:
self.logger.error("提醒路由器解析失败: %s", exc, exc_info=True)
return None
def json_response(raw: str) -> str:
"""从模型返回的文本中提取 JSON。"""
try:
start = raw.index("{")
end = raw.rindex("}") + 1
return raw[start:end]
except ValueError:
return "{}"
reminder_router = ReminderRouter()