Упрощение: общие хелперы, команды и упоминания по entities, фото только для моделей со зрением

- Одна formatUtc и один displayName(profile) вместо копий в разных слоях
- commandOf/mentionsUser/textWithoutMention работают по entities для текста и подписей;
  убраны askInCaption, regex-поиск упоминаний и отдельный composer.command("ask")
- Фото скачиваются только если модель их видит; пустой вопрос с картинкой формулирует промпт
- Поддержка фото задаётся явно для моделей по умолчанию, для своей AI_MODEL — через AI_IMAGE_INPUT
- Активность участников считается по сохранённой истории, а не отдельными счётчиками;
  один хендлер для message и edited_message, упоминания не пишутся дважды
- SQLite: synchronous = NORMAL для WAL
- Кнопки не-админов отклоняются через bot.drop(isAdmin)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
yunogasai
2026-09-24 20:10:56 +02:00
parent f8273e8a23
commit e812f1b1e2
21 changed files with 269 additions and 266 deletions

View File

@@ -20,23 +20,25 @@ export interface ChatMessage {
/** Участник чата, которого бот видел: писал сам или был упомянут по имени-ссылке. */
export interface ChatMember {
chatId: number;
userId: number;
username: string | null;
firstName: string;
lastName: string | null;
/** Сколько его сообщений в сохранённой истории чата. */
messageCount: number;
/** Unix-время последнего сообщения; 0 — ещё не писал (только упоминали). */
/** Unix-время последнего сохранённого сообщения; 0 — сообщений в истории нет. */
lastSeen: number;
}
/** Данные пользователя Telegram, которые бот запоминает об участнике. */
export type MemberProfile = Pick<ChatMember, "userId" | "username" | "firstName" | "lastName">;
/** Откуда фото: из самого вопроса или из сообщения, на которое ответил спрашивающий. */
export type ImageSource = "question" | "replied";
/** Картинка, которую бот передаёт модели вместе с вопросом. */
export interface ImageAttachment {
data: Uint8Array;
mimeType: string;
/** Откуда фото: из самого вопроса или из сообщения, на которое ответил спрашивающий. */
source: "question" | "replied";
source: ImageSource;
}