Telegram-бот Boltun AI на grammY + Mastra

- Отвечает только администраторам из ADMIN_IDS
- Личности на чат: встроенные и пользовательские (/personas, /persona, /persona_add, /persona_del)
- Вопросы через /ask, упоминание, ответ боту или личку
- Сохраняет сообщения чата в SQLite; агент по просьбе читает их инструментом read_chat_messages
- Модели через OpenRouter (по умолчанию DeepSeek)
- Слои: libs, repositories, services, bot/handlers
- Dockerfile для деплоя в Dokploy

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
yunogasai
2026-09-24 18:31:44 +02:00
commit 99c4660da9
32 changed files with 3173 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
import { createTool } from "@mastra/core/tools";
import { z } from "zod";
import type { ChatHistoryService } from "../../chat-history-service.js";
import { formatChatMessages } from "../format-chat-messages.js";
const MAX_HISTORY_READ = 300;
const assistantRequestContextSchema = z.object({ chatId: z.number() });
export type AssistantRequestContext = z.infer<typeof assistantRequestContextSchema>;
export const createReadChatMessagesTool = (chatHistoryService: ChatHistoryService) =>
createTool({
id: "read_chat_messages",
description:
"Загружает последние сообщения текущего Telegram-чата (включая твои ответы). " +
"Вызывай, когда пользователь просит посмотреть, прочитать, пересказать или проанализировать " +
"сообщения/переписку в чате, или когда без контекста беседы ответить нельзя.",
inputSchema: z.object({
limit: z
.number()
.int()
.min(1)
.max(MAX_HISTORY_READ)
.default(50)
.describe(`Сколько последних сообщений загрузить (1–${MAX_HISTORY_READ}).`),
}),
requestContextSchema: assistantRequestContextSchema,
execute: async ({ limit }, { requestContext }) => {
const messages = chatHistoryService.latest(requestContext.get("chatId"), limit);
return {
count: messages.length,
messages: messages.length > 0 ? formatChatMessages(messages) : "В сохранённой истории чата пока нет сообщений.",
};
},
});