Участники чата, промпты в файлах, личности только из кода

- Бот запоминает участников (имя, фамилия, ник, активность) и ID автора каждого сообщения
- Упоминания в вопросе (@ник и по имени-ссылке) передаются модели с данными участника
- Новые инструменты агента: list_chat_members, read_member_messages (поиск по нику/имени)
- Бот обращается к людям по имени
- Промпты вынесены в prompts/system.md и prompts/personas/<id>.md
- Личности больше не редактируются из чата: скрипт seed синхронизирует их с БД при старте
- Оставлена одна личность boltun (Dirty D)
- Миграция старых баз: колонка messages.user_id

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
yunogasai
2026-09-24 18:42:23 +02:00
parent 99c4660da9
commit 26da4bb5ee
35 changed files with 567 additions and 241 deletions

View File

@@ -1,36 +1,48 @@
import { Agent } from "@mastra/core/agent";
import { RequestContext } from "@mastra/core/request-context";
import { readPrompt } from "../../libs/prompts.js";
import type { Persona } from "../../types.js";
import type { ChatHistoryService } from "../chat-history-service.js";
import { BASE_RULES, buildInstructions, buildPrompt, type Question } from "./prompts.js";
import { createReadChatMessagesTool, type AssistantRequestContext } from "./tools/read-chat-messages-tool.js";
import type { ChatMemberService } from "../chat-member-service.js";
import { buildInstructions, buildPrompt, type Question } from "./prompts.js";
import { createListChatMembersTool } from "./tools/list-chat-members-tool.js";
import { createReadChatMessagesTool } from "./tools/read-chat-messages-tool.js";
import { createReadMemberMessagesTool } from "./tools/read-member-messages-tool.js";
import type { AssistantRequestContext } from "./tools/request-context.js";
export type { Question } from "./prompts.js";
interface AssistantServiceDeps {
model: string;
chatHistoryService: ChatHistoryService;
chatMemberService: ChatMemberService;
}
const MAX_AGENT_STEPS = 5;
const MAX_AGENT_STEPS = 6;
export const createAssistantService = ({ model, chatHistoryService, chatMemberService }: AssistantServiceDeps) => {
const systemRules = readPrompt("system.md");
export const createAssistantService = ({ model, chatHistoryService }: AssistantServiceDeps) => {
const agent = new Agent({
id: "boltun",
name: "Boltun",
instructions: BASE_RULES,
instructions: systemRules,
model,
tools: { readChatMessages: createReadChatMessagesTool(chatHistoryService) },
tools: {
readChatMessages: createReadChatMessagesTool(chatHistoryService),
listChatMembers: createListChatMembersTool(chatMemberService),
readMemberMessages: createReadMemberMessagesTool({ chatHistoryService, chatMemberService }),
},
});
/** Ответ на вопрос в образе личности; агент сам решает, нужно ли читать историю чата. */
/** Ответ на вопрос в образе личности; агент сам решает, какую историю чата подгрузить. */
const answer = async (question: Question, persona: Persona): Promise<string> => {
const requestContext = new RequestContext<AssistantRequestContext>();
requestContext.set("chatId", question.chatId);
const result = await agent.generate(buildPrompt(question), {
instructions: buildInstructions(question, persona),
instructions: buildInstructions(systemRules, question, persona),
requestContext,
maxSteps: MAX_AGENT_STEPS,
});