135 lines
4.9 KiB
Python
135 lines
4.9 KiB
Python
from typing import Any
|
||
|
||
from app.reminders_scoped.service import RemindersService
|
||
from app.tools._dispatch import NOT_HANDLED, ToolContext
|
||
|
||
TOOL_NAMES = frozenset({
|
||
"list_reminders",
|
||
"create_reminder",
|
||
"update_reminder",
|
||
"delete_reminder",
|
||
"complete_reminder",
|
||
})
|
||
|
||
TOOL_DEFINITIONS: list[dict[str, Any]] = [
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "list_reminders",
|
||
"description": "Список активных напоминаний. «Что напомнил», «мои напоминания».",
|
||
"parameters": {
|
||
"type": "object",
|
||
"properties": {
|
||
"limit": {"type": "integer", "description": "Макс. записей, по умолчанию 20"},
|
||
},
|
||
"required": [],
|
||
},
|
||
},
|
||
},
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "create_reminder",
|
||
"description": (
|
||
"Создать напоминание. due_at — ISO datetime в часовом поясе пользователя "
|
||
"(см. [Текущее время]). Примеры: через 15 мин, завтра 09:00, 2027-05-12T12:16:00."
|
||
),
|
||
"parameters": {
|
||
"type": "object",
|
||
"properties": {
|
||
"title": {"type": "string", "description": "О чём напомнить"},
|
||
"due_at": {"type": "string", "description": "ISO datetime"},
|
||
"notes": {"type": "string"},
|
||
"all_day": {"type": "boolean"},
|
||
"recurrence": {
|
||
"type": "string",
|
||
"enum": ["none", "daily", "weekly", "monthly", "yearly"],
|
||
"description": "Повтор (yearly — день рождения, Новый год)",
|
||
},
|
||
},
|
||
"required": ["title", "due_at"],
|
||
},
|
||
},
|
||
},
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "update_reminder",
|
||
"description": "Изменить напоминание по id.",
|
||
"parameters": {
|
||
"type": "object",
|
||
"properties": {
|
||
"reminder_id": {"type": "integer"},
|
||
"title": {"type": "string"},
|
||
"due_at": {"type": "string"},
|
||
"notes": {"type": "string"},
|
||
"all_day": {"type": "boolean"},
|
||
"recurrence": {
|
||
"type": "string",
|
||
"enum": ["none", "daily", "weekly", "monthly", "yearly"],
|
||
},
|
||
"enabled": {"type": "boolean"},
|
||
},
|
||
"required": ["reminder_id"],
|
||
},
|
||
},
|
||
},
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "delete_reminder",
|
||
"description": "Удалить напоминание по id.",
|
||
"parameters": {
|
||
"type": "object",
|
||
"properties": {"reminder_id": {"type": "integer"}},
|
||
"required": ["reminder_id"],
|
||
},
|
||
},
|
||
},
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "complete_reminder",
|
||
"description": "Отметить напоминание выполненным (снять с календаря).",
|
||
"parameters": {
|
||
"type": "object",
|
||
"properties": {"reminder_id": {"type": "integer"}},
|
||
"required": ["reminder_id"],
|
||
},
|
||
},
|
||
},
|
||
]
|
||
|
||
|
||
async def execute(name: str, arguments: dict[str, Any], ctx: ToolContext) -> Any:
|
||
if name not in TOOL_NAMES:
|
||
return NOT_HANDLED
|
||
|
||
reminders = RemindersService(ctx.db, ctx.user_id)
|
||
|
||
if name == "list_reminders":
|
||
return reminders.list_upcoming(limit=int(arguments.get("limit") or 20))
|
||
if name == "create_reminder":
|
||
return reminders.create(
|
||
title=arguments.get("title", ""),
|
||
due_at=arguments.get("due_at", ""),
|
||
notes=arguments.get("notes", ""),
|
||
all_day=bool(arguments.get("all_day", False)),
|
||
recurrence=arguments.get("recurrence", "none"),
|
||
)
|
||
if name == "update_reminder":
|
||
return reminders.update(
|
||
int(arguments["reminder_id"]),
|
||
title=arguments.get("title"),
|
||
due_at=arguments.get("due_at"),
|
||
notes=arguments.get("notes"),
|
||
all_day=arguments.get("all_day"),
|
||
recurrence=arguments.get("recurrence"),
|
||
enabled=arguments.get("enabled"),
|
||
)
|
||
if name == "delete_reminder":
|
||
return reminders.delete(int(arguments["reminder_id"]))
|
||
if name == "complete_reminder":
|
||
return reminders.complete(int(arguments["reminder_id"]))
|
||
return NOT_HANDLED
|