Участники чата, промпты в файлах, личности только из кода
- Бот запоминает участников (имя, фамилия, ник, активность) и 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:
@@ -4,6 +4,7 @@ import type { ChatMessage } from "../types.js";
|
||||
interface MessageRow {
|
||||
chat_id: number;
|
||||
message_id: number;
|
||||
user_id: number | null;
|
||||
date: number;
|
||||
author: string;
|
||||
text: string;
|
||||
@@ -13,6 +14,7 @@ interface MessageRow {
|
||||
const toMessage = (row: MessageRow): ChatMessage => ({
|
||||
chatId: row.chat_id,
|
||||
messageId: row.message_id,
|
||||
userId: row.user_id,
|
||||
date: row.date,
|
||||
author: row.author,
|
||||
text: row.text,
|
||||
@@ -22,8 +24,8 @@ const toMessage = (row: MessageRow): ChatMessage => ({
|
||||
export const createMessageRepository = (db: Db) => {
|
||||
const statements = {
|
||||
upsert: db.prepare(`
|
||||
INSERT INTO messages (chat_id, message_id, date, author, text, reply_to_message_id)
|
||||
VALUES (@chatId, @messageId, @date, @author, @text, @replyToMessageId)
|
||||
INSERT INTO messages (chat_id, message_id, user_id, date, author, text, reply_to_message_id)
|
||||
VALUES (@chatId, @messageId, @userId, @date, @author, @text, @replyToMessageId)
|
||||
ON CONFLICT(chat_id, message_id) DO UPDATE SET text = excluded.text
|
||||
`),
|
||||
pruneChat: db.prepare(`
|
||||
@@ -33,9 +35,14 @@ export const createMessageRepository = (db: Db) => {
|
||||
)
|
||||
`),
|
||||
latest: db.prepare("SELECT * FROM messages WHERE chat_id = ? ORDER BY message_id DESC LIMIT ?"),
|
||||
latestByUser: db.prepare(
|
||||
"SELECT * FROM messages WHERE chat_id = ? AND user_id = ? ORDER BY message_id DESC LIMIT ?",
|
||||
),
|
||||
findById: db.prepare("SELECT * FROM messages WHERE chat_id = ? AND message_id = ?"),
|
||||
};
|
||||
|
||||
const toChronological = (rows: unknown[]): ChatMessage[] => (rows as MessageRow[]).reverse().map(toMessage);
|
||||
|
||||
/** Сохраняет сообщение (при повторе — обновляет текст) и оставляет в чате не больше `keep` последних. */
|
||||
const upsertAndPrune = db.transaction((message: ChatMessage, keep: number) => {
|
||||
statements.upsert.run(message);
|
||||
@@ -44,7 +51,11 @@ export const createMessageRepository = (db: Db) => {
|
||||
|
||||
/** Последние `limit` сообщений чата в хронологическом порядке. */
|
||||
const latest = (chatId: number, limit: number): ChatMessage[] =>
|
||||
(statements.latest.all(chatId, limit) as MessageRow[]).reverse().map(toMessage);
|
||||
toChronological(statements.latest.all(chatId, limit));
|
||||
|
||||
/** Последние `limit` сообщений конкретного участника в хронологическом порядке. */
|
||||
const latestByUser = (chatId: number, userId: number, limit: number): ChatMessage[] =>
|
||||
toChronological(statements.latestByUser.all(chatId, userId, limit));
|
||||
|
||||
const findById = (chatId: number, messageId: number): ChatMessage | undefined => {
|
||||
const row = statements.findById.get(chatId, messageId) as MessageRow | undefined;
|
||||
@@ -52,7 +63,7 @@ export const createMessageRepository = (db: Db) => {
|
||||
return row && toMessage(row);
|
||||
};
|
||||
|
||||
return { upsertAndPrune, latest, findById };
|
||||
return { upsertAndPrune, latest, latestByUser, findById };
|
||||
};
|
||||
|
||||
export type MessageRepository = ReturnType<typeof createMessageRepository>;
|
||||
|
||||
Reference in New Issue
Block a user