bump libs
migrate to typescript 6 remove ytdl feature
This commit is contained in:
@@ -18,7 +18,7 @@ export class AdminsAdd extends Command {
|
||||
);
|
||||
|
||||
async execute(msg: Message): Promise<void> {
|
||||
if (!msg.reply_to_message) return;
|
||||
if (!msg.reply_to_message || !msg.reply_to_message.from) return;
|
||||
|
||||
const id = msg.reply_to_message.from.id;
|
||||
const text = fullName(msg.reply_to_message.from);
|
||||
|
||||
@@ -18,7 +18,7 @@ export class AdminsRemove extends Command {
|
||||
);
|
||||
|
||||
async execute(msg: Message): Promise<void> {
|
||||
if (!msg.reply_to_message) return;
|
||||
if (!msg.reply_to_message || !msg.reply_to_message.from) return;
|
||||
|
||||
const id = msg.reply_to_message.from.id;
|
||||
const text = fullName(msg.reply_to_message.from);
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ export class Ae extends Command {
|
||||
requirements = Requirements.Build(Requirement.BOT_CREATOR);
|
||||
|
||||
async execute(msg: Message, params?: RegExpExecArray) {
|
||||
const match = params?.[3];
|
||||
const match = params?.[3] || "";
|
||||
|
||||
try {
|
||||
let e = eval(match);
|
||||
@@ -21,7 +21,7 @@ export class Ae extends Command {
|
||||
e = ((typeof e == "string") ? e : JSON.stringify(e));
|
||||
|
||||
await oldSendMessage(msg, e).catch(async () => await errorPlaceholder(msg));
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
const text = e.message.toString();
|
||||
|
||||
if (text.includes("is not defined")) {
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ export class Ban extends Command {
|
||||
);
|
||||
|
||||
async execute(msg: Message) {
|
||||
if (!msg.reply_to_message) return;
|
||||
if (!msg.reply_to_message || !msg.from || ! msg.reply_to_message.from) return;
|
||||
|
||||
const user = msg.reply_to_message.from;
|
||||
const userId = user.id;
|
||||
|
||||
@@ -12,7 +12,7 @@ export class Choice extends Command {
|
||||
async execute(msg: Message, match?: RegExpExecArray): Promise<void> {
|
||||
console.log("match", match);
|
||||
|
||||
const payload = match[3];
|
||||
const payload = match?.[3] || "";
|
||||
|
||||
const re =
|
||||
/\s*(?:"((?:\\.|[^"\\])*)"|'((?:\\.|[^'\\])*)'|([^,]+?))\s*(?:,|$)/g;
|
||||
|
||||
@@ -11,8 +11,8 @@ export class Dice extends Command {
|
||||
description = "Sends random or specific dice";
|
||||
|
||||
async execute(msg: Message): Promise<void> {
|
||||
const split = msg.text.split("/dice ");
|
||||
const secondPart = split[1]?.trim();
|
||||
const split = msg.text?.split("/dice ");
|
||||
const secondPart = split?.[1]?.trim() || "";
|
||||
const emojiIndex = emojis.indexOf(secondPart);
|
||||
const emojiToDice: DiceEmoji = (emojiIndex >= 0 ? emojis[emojiIndex] : randomValue(emojis)) as DiceEmoji;
|
||||
|
||||
|
||||
@@ -47,14 +47,14 @@ export class Distort extends Command {
|
||||
|
||||
const inputBuf = await downloadTelegramFile(file.file_path);
|
||||
|
||||
const outBuf = await waveDistortSharp(inputBuf, amp, wavelength);
|
||||
const outBuf = await waveDistortSharp(<Buffer>inputBuf, amp, wavelength);
|
||||
|
||||
await bot.sendPhoto({
|
||||
chat_id: chatId,
|
||||
photo: outBuf,
|
||||
caption: `Искажение готово ✅ (amp=${amp}, wavelength=${wavelength})`,
|
||||
});
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
await oldReplyToMessage(
|
||||
msg, `Не получилось исказить изображение: ${e?.message ?? String(e)}`
|
||||
).catch(logError);
|
||||
|
||||
+22
-17
@@ -4,7 +4,7 @@ import {bot, googleAi} from "../index";
|
||||
import {MessageStore} from "../common/message-store";
|
||||
import {Requirements} from "../base/requirements";
|
||||
import {Requirement} from "../base/requirement";
|
||||
import {ApiError} from "@google/genai";
|
||||
|
||||
import {
|
||||
collectReplyChainText,
|
||||
escapeMarkdownV2Text,
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
startIntervalEditor
|
||||
} from "../util/utils";
|
||||
import {ChatCommand} from "../base/chat-command";
|
||||
import {ApiError} from "@google/genai";
|
||||
|
||||
export class GeminiChat extends ChatCommand {
|
||||
command = "gemini";
|
||||
@@ -26,11 +27,11 @@ export class GeminiChat extends ChatCommand {
|
||||
|
||||
async execute(msg: Message, match?: RegExpExecArray): Promise<void> {
|
||||
console.log("match", match);
|
||||
return this.executeGemini(msg, match?.[3]);
|
||||
return this.executeGemini(msg, match?.[3] || "");
|
||||
}
|
||||
|
||||
async executeGemini(msg: Message, text: string): Promise<void> {
|
||||
if (!text || text.trim().length === 0) return;
|
||||
if (!text || !text.trim().length) return;
|
||||
|
||||
const chatId = msg.chat.id;
|
||||
|
||||
@@ -77,7 +78,7 @@ export class GeminiChat extends ChatCommand {
|
||||
});
|
||||
}
|
||||
|
||||
let waitMessage: Message;
|
||||
let waitMessage: Message | null = null;
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
@@ -95,7 +96,7 @@ export class GeminiChat extends ChatCommand {
|
||||
|
||||
const stream = await googleAi.interactions.create({
|
||||
model: Environment.GEMINI_MODEL,
|
||||
input: input,
|
||||
input: input as any,
|
||||
stream: true
|
||||
});
|
||||
|
||||
@@ -109,7 +110,7 @@ export class GeminiChat extends ChatCommand {
|
||||
await bot.editMessageText(
|
||||
{
|
||||
chat_id: chatId,
|
||||
message_id: waitMessage.message_id,
|
||||
message_id: <number>waitMessage?.message_id,
|
||||
text: escapeMarkdownV2Text(text),
|
||||
parse_mode: "MarkdownV2"
|
||||
}
|
||||
@@ -117,9 +118,11 @@ export class GeminiChat extends ChatCommand {
|
||||
|
||||
console.log("editMessageText", text);
|
||||
|
||||
waitMessage.reply_to_message = msg;
|
||||
waitMessage.text = text;
|
||||
await MessageStore.put(waitMessage);
|
||||
if (waitMessage) {
|
||||
waitMessage.reply_to_message = msg;
|
||||
waitMessage.text = text;
|
||||
await MessageStore.put(waitMessage);
|
||||
}
|
||||
},
|
||||
onStop: async () => {
|
||||
}
|
||||
@@ -175,17 +178,19 @@ export class GeminiChat extends ChatCommand {
|
||||
await replyToMessage({message: waitMessage, text: `⏱️ ${diff}s`});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logError(error);
|
||||
} catch (e: any) {
|
||||
logError(e);
|
||||
|
||||
if (error instanceof ApiError) {
|
||||
if (error.status === 429) {
|
||||
await oldReplyToMessage(waitMessage, "На сегодня всё, лимиты закончились.").catch(logError);
|
||||
return;
|
||||
if (waitMessage) {
|
||||
if (e instanceof ApiError) {
|
||||
if (e.status === 429) {
|
||||
await oldReplyToMessage(waitMessage, "На сегодня всё, лимиты закончились.").catch(logError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await oldReplyToMessage(waitMessage, `Произошла ошибка!\n${error.toString()}`).catch(logError);
|
||||
await oldReplyToMessage(waitMessage, `Произошла ошибка!\n${e.toString()}`).catch(logError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,14 +18,14 @@ export class GeminiGenerateImage extends Command {
|
||||
async execute(msg: Message, match?: RegExpExecArray): Promise<void> {
|
||||
console.log("match", match);
|
||||
|
||||
const prompt = match?.[3];
|
||||
const prompt = match?.[3] || "";
|
||||
return this.executeGenImage(msg, prompt);
|
||||
}
|
||||
|
||||
async executeGenImage(msg: Message, text: string): Promise<void> {
|
||||
if (!text || text.trim().length === 0) return;
|
||||
if (!text || !text.trim().length) return;
|
||||
|
||||
let waitMessage: Message;
|
||||
let waitMessage: Message | null = null;
|
||||
|
||||
try {
|
||||
waitMessage = await replyToMessage({
|
||||
@@ -47,14 +47,16 @@ export class GeminiGenerateImage extends Command {
|
||||
console.log(`Output ${index + 1}: ${output}`);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
logError(e);
|
||||
|
||||
await replyToMessage({
|
||||
message: waitMessage,
|
||||
text: `Произошла ошибка!\n${e.toString()}`,
|
||||
link_preview_options: {is_disabled: true}
|
||||
}).catch(logError);
|
||||
if (waitMessage) {
|
||||
await replyToMessage({
|
||||
message: waitMessage,
|
||||
text: `Произошла ошибка!\n${e.toString()}`,
|
||||
link_preview_options: {is_disabled: true}
|
||||
}).catch(logError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,9 @@ export class GeminiGetModel extends Command {
|
||||
|
||||
return {
|
||||
vision: {supported: true},
|
||||
ocr: null,
|
||||
ocr: undefined,
|
||||
thinking: {supported: info.thinking},
|
||||
tools: null
|
||||
tools: undefined
|
||||
};
|
||||
} catch (e) {
|
||||
logError(e);
|
||||
|
||||
@@ -17,7 +17,7 @@ export class GeminiListModels extends Command {
|
||||
console.log(listResponse);
|
||||
|
||||
const modelsString = listResponse.page
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.sort((a, b) => (a.name || "").localeCompare((b.name || "")))
|
||||
.map(e => `${e.name}`)
|
||||
.join("\n");
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ export class Help extends Command {
|
||||
description = "Show list of commands";
|
||||
|
||||
async execute(msg: Message) {
|
||||
if (!msg.from) return;
|
||||
let text = "Commands:\n\n";
|
||||
|
||||
commands.forEach(c => {
|
||||
|
||||
+2
-2
@@ -7,9 +7,9 @@ export class Id extends Command {
|
||||
description = "ID of chat, user and reply (if replied to any message)";
|
||||
|
||||
async execute(msg: Message): Promise<void> {
|
||||
let text = `chat id: \n\`\`\`${msg.chat.id}\`\`\` \nfrom id: \n\`\`\`${msg.from.id}\`\`\``;
|
||||
let text = `chat id: \n\`\`\`${msg.chat.id}\`\`\` \nfrom id: \n\`\`\`${msg.from?.id}\`\`\``;
|
||||
if (msg.reply_to_message) {
|
||||
text += ` \nreply id: \n\`\`\`${msg.reply_to_message.from.id}\`\`\``;
|
||||
text += ` \nreply id: \n\`\`\`${msg.reply_to_message.from?.id}\`\`\``;
|
||||
}
|
||||
|
||||
await oldReplyToMessage(msg, text, "MarkdownV2").catch(logError);
|
||||
|
||||
@@ -19,7 +19,7 @@ export class Ignore extends Command {
|
||||
);
|
||||
|
||||
async execute(msg: Message) {
|
||||
if (!msg.reply_to_message) return;
|
||||
if (!msg.reply_to_message || !msg.reply_to_message.from) return;
|
||||
|
||||
const id = msg.reply_to_message.from.id;
|
||||
const text = fullName(msg.reply_to_message.from);
|
||||
|
||||
@@ -16,7 +16,7 @@ export class Info extends Command {
|
||||
async execute(msg: Message): Promise<void> {
|
||||
const aiProvider = Environment.DEFAULT_AI_PROVIDER;
|
||||
const aiModel = getCurrentModel();
|
||||
let aiModelCapabilities: AiModelCapabilities = {};
|
||||
let aiModelCapabilities: AiModelCapabilities | null = {};
|
||||
|
||||
try {
|
||||
aiModelCapabilities = await getCurrentModelCapabilities();
|
||||
@@ -33,11 +33,11 @@ export class Info extends Command {
|
||||
|
||||
`provider: ${aiProvider.toLowerCase()}\n` +
|
||||
`model: ${aiModel}\n\n` +
|
||||
`vision${aiModelCapabilities.vision?.external ? "(ext)" : ""}: ${boolToEmoji(aiModelCapabilities.vision?.supported)}\n` +
|
||||
`ocr${aiModelCapabilities.ocr?.external ? "(ext)" : ""}: ${boolToEmoji(aiModelCapabilities.ocr?.supported)}\n` +
|
||||
`thinking${aiModelCapabilities.thinking?.external ? "(ext)" : ""}: ${boolToEmoji(aiModelCapabilities.thinking?.supported)}\n` +
|
||||
`tools${aiModelCapabilities.tools?.external ? "(ext)" : ""}: ${boolToEmoji(aiModelCapabilities.tools?.supported)}\n` +
|
||||
`audio${aiModelCapabilities.audio?.external ? "(ext)": ""}: ${boolToEmoji(aiModelCapabilities.audio?.supported)}` +
|
||||
`vision${aiModelCapabilities?.vision?.external ? "(ext)" : ""}: ${boolToEmoji(aiModelCapabilities?.vision?.supported)}\n` +
|
||||
`ocr${aiModelCapabilities?.ocr?.external ? "(ext)" : ""}: ${boolToEmoji(aiModelCapabilities?.ocr?.supported)}\n` +
|
||||
`thinking${aiModelCapabilities?.thinking?.external ? "(ext)" : ""}: ${boolToEmoji(aiModelCapabilities?.thinking?.supported)}\n` +
|
||||
`tools${aiModelCapabilities?.tools?.external ? "(ext)" : ""}: ${boolToEmoji(aiModelCapabilities?.tools?.supported)}\n` +
|
||||
`audio${aiModelCapabilities?.audio?.external ? "(ext)" : ""}: ${boolToEmoji(aiModelCapabilities?.audio?.supported)}` +
|
||||
"```";
|
||||
|
||||
const cmds = commands.filter(c => !(c instanceof ChatCommand));
|
||||
|
||||
@@ -26,11 +26,11 @@ export class MistralChat extends ChatCommand {
|
||||
|
||||
async execute(msg: Message, match?: RegExpExecArray): Promise<void> {
|
||||
console.log("match", match);
|
||||
return this.executeMistral(msg, match?.[3]);
|
||||
return this.executeMistral(msg, match?.[3] || "");
|
||||
}
|
||||
|
||||
async executeMistral(msg: Message, text: string): Promise<void> {
|
||||
if (!text || text.trim().length === 0) return;
|
||||
if (!text || !text.trim().length) return;
|
||||
|
||||
const chatId = msg.chat.id;
|
||||
|
||||
@@ -63,7 +63,7 @@ export class MistralChat extends ChatCommand {
|
||||
chatMessages.unshift({role: "system", content: [{type: "text", text: Environment.SYSTEM_PROMPT}]});
|
||||
}
|
||||
|
||||
let waitMessage: Message;
|
||||
let waitMessage: Message | null = null;
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
@@ -74,7 +74,7 @@ export class MistralChat extends ChatCommand {
|
||||
|
||||
if (imagesCount) {
|
||||
try {
|
||||
const modelInfo = await commands.find(c => c instanceof MistralGetModel).getModelCapabilities();
|
||||
const modelInfo = await commands.find(c => c instanceof MistralGetModel)?.getModelCapabilities();
|
||||
if (modelInfo) {
|
||||
if (!modelInfo.vision?.supported) {
|
||||
await replyToMessage({
|
||||
@@ -117,7 +117,7 @@ export class MistralChat extends ChatCommand {
|
||||
await bot.editMessageText(
|
||||
{
|
||||
chat_id: chatId,
|
||||
message_id: waitMessage.message_id,
|
||||
message_id: <number>waitMessage?.message_id,
|
||||
text: escapeMarkdownV2Text(text),
|
||||
parse_mode: "MarkdownV2"
|
||||
}
|
||||
@@ -125,9 +125,11 @@ export class MistralChat extends ChatCommand {
|
||||
|
||||
console.log("editMessageText", text);
|
||||
|
||||
waitMessage.reply_to_message = msg;
|
||||
waitMessage.text = text;
|
||||
await MessageStore.put(waitMessage);
|
||||
if (waitMessage) {
|
||||
waitMessage.reply_to_message = msg;
|
||||
waitMessage.text = text;
|
||||
await MessageStore.put(waitMessage);
|
||||
}
|
||||
},
|
||||
onStop: async () => {
|
||||
}
|
||||
@@ -172,9 +174,12 @@ export class MistralChat extends ChatCommand {
|
||||
await replyToMessage({message: waitMessage, text: `⏱️ ${diff}s`});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logError(error);
|
||||
await oldReplyToMessage(waitMessage, `Произошла ошибка!\n${error.toString()}`).catch(logError);
|
||||
} catch (e: any) {
|
||||
logError(e);
|
||||
|
||||
if (waitMessage) {
|
||||
await oldReplyToMessage(waitMessage, `Произошла ошибка!\n${e.toString()}`).catch(logError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import {Requirements} from "../base/requirements";
|
||||
import {Requirement} from "../base/requirement";
|
||||
import {mistralAi} from "../index";
|
||||
import {AiModelCapabilities} from "../model/ai-model-capabilities";
|
||||
import {BaseModelCard} from "@mistralai/mistralai/models/components/basemodelcard";
|
||||
|
||||
export class MistralGetModel extends Command {
|
||||
title = "/mistralGetModel";
|
||||
@@ -20,13 +19,13 @@ export class MistralGetModel extends Command {
|
||||
|
||||
async getModelCapabilities(): Promise<AiModelCapabilities | null> {
|
||||
try {
|
||||
const info: BaseModelCard = await mistralAi.models.retrieve({modelId: Environment.MISTRAL_MODEL}) as BaseModelCard;
|
||||
const info = await mistralAi.models.retrieve({modelId: Environment.MISTRAL_MODEL}) as any;
|
||||
console.log(info);
|
||||
|
||||
return {
|
||||
vision: {supported: info.capabilities.vision},
|
||||
ocr: {supported: info.capabilities.ocr},
|
||||
thinking: null,
|
||||
thinking: undefined,
|
||||
tools: {supported: info.capabilities.functionCalling},
|
||||
audio: {supported: info.capabilities.audioTranscription}
|
||||
};
|
||||
|
||||
@@ -4,7 +4,6 @@ import {Requirement} from "../base/requirement";
|
||||
import {Message} from "typescript-telegram-bot-api";
|
||||
import {mistralAi} from "../index";
|
||||
import {logError, oldReplyToMessage, replyToMessage} from "../util/utils";
|
||||
import {BaseModelCard} from "@mistralai/mistralai/models/components/basemodelcard";
|
||||
|
||||
export class MistralListModels extends Command {
|
||||
title = "/mistralListModels";
|
||||
@@ -21,7 +20,7 @@ export class MistralListModels extends Command {
|
||||
console.log(listResponse);
|
||||
|
||||
const modelsString = listResponse.data
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.sort((a, b) => a?.name?.localeCompare(b.name || "") || -1)
|
||||
.map(e => `${e.id}`)
|
||||
.join("\n");
|
||||
|
||||
@@ -37,4 +36,42 @@ export class MistralListModels extends Command {
|
||||
await oldReplyToMessage(msg, "Не получилось загрузить список моделей").catch(logError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type BaseModelCard = {
|
||||
id: string;
|
||||
object: string;
|
||||
created?: number | undefined;
|
||||
ownedBy: string;
|
||||
/**
|
||||
* This is populated by Harmattan, but some fields have a name
|
||||
*
|
||||
* @remarks
|
||||
* that we don't want to expose in the API.
|
||||
*/
|
||||
capabilities: ModelCapabilities;
|
||||
name?: string | null | undefined;
|
||||
description?: string | null | undefined;
|
||||
maxContextLength: number;
|
||||
aliases?: Array<string> | undefined;
|
||||
deprecation?: Date | null | undefined;
|
||||
deprecationReplacementModel?: string | null | undefined;
|
||||
defaultModelTemperature?: number | null | undefined;
|
||||
type: "base";
|
||||
};
|
||||
|
||||
type ModelCapabilities = {
|
||||
completionChat: boolean;
|
||||
functionCalling: boolean;
|
||||
reasoning: boolean;
|
||||
completionFim: boolean;
|
||||
fineTuning: boolean;
|
||||
vision: boolean;
|
||||
ocr: boolean;
|
||||
classification: boolean;
|
||||
moderation: boolean;
|
||||
audio: boolean;
|
||||
audioTranscription: boolean;
|
||||
audioTranscriptionRealtime: boolean;
|
||||
audioSpeech: boolean;
|
||||
};
|
||||
+27
-22
@@ -28,11 +28,12 @@ export class OllamaChat extends ChatCommand {
|
||||
|
||||
async execute(msg: Message, match?: RegExpExecArray | null): Promise<void> {
|
||||
console.log("match", match);
|
||||
return this.executeOllama(msg, match?.[3], match?.[1]?.toLowerCase()?.startsWith("ollamathink"));
|
||||
return this.executeOllama(msg, match?.[3] || "", match?.[1]?.toLowerCase()?.startsWith("ollamathink"));
|
||||
}
|
||||
|
||||
async executeOllama(msg: Message, text: string, think: boolean = false, voiceB64?: string): Promise<void> {
|
||||
if ((!text || text.trim().length === 0) && !voiceB64) return;
|
||||
async executeOllama(msg: Message, text: string, think: boolean = false, voiceB64?: string | null): Promise<void> {
|
||||
if (!msg.from) return;
|
||||
if ((!text || !text.trim().length) && !voiceB64) return;
|
||||
|
||||
const chatId = msg.chat.id;
|
||||
|
||||
@@ -66,7 +67,7 @@ export class OllamaChat extends ChatCommand {
|
||||
chatMessages.unshift({role: "system", content: Environment.SYSTEM_PROMPT, images: []});
|
||||
}
|
||||
|
||||
let waitMessage: Message;
|
||||
let waitMessage: Message | null = null;
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
@@ -77,7 +78,7 @@ export class OllamaChat extends ChatCommand {
|
||||
|
||||
if (!think && imagesCount) {
|
||||
try {
|
||||
const modelInfo = await commands.find(c => c instanceof OllamaGetModel).loadImageModelInfo();
|
||||
const modelInfo = await commands.find(c => c instanceof OllamaGetModel)?.loadImageModelInfo();
|
||||
if (modelInfo) {
|
||||
if (!modelInfo.vision?.supported) {
|
||||
await replyToMessage({
|
||||
@@ -94,7 +95,7 @@ export class OllamaChat extends ChatCommand {
|
||||
|
||||
if (think) {
|
||||
try {
|
||||
const modelInfo = await commands.find(c => c instanceof OllamaGetModel).loadThinkModelInfo();
|
||||
const modelInfo = await commands.find(c => c instanceof OllamaGetModel)?.loadThinkModelInfo();
|
||||
if (modelInfo) {
|
||||
if (!modelInfo.thinking?.supported) {
|
||||
await replyToMessage({
|
||||
@@ -131,11 +132,11 @@ export class OllamaChat extends ChatCommand {
|
||||
}
|
||||
|
||||
const stream = await ollama.chat({
|
||||
model: think ? Environment.OLLAMA_THINK_MODEL : imagesCount ? Environment.OLLAMA_IMAGE_MODEL : Environment.OLLAMA_MODEL,
|
||||
model: <string>(think ? Environment.OLLAMA_THINK_MODEL : imagesCount ? Environment.OLLAMA_IMAGE_MODEL : Environment.OLLAMA_MODEL),
|
||||
stream: true,
|
||||
think: think,
|
||||
messages: chatMessages,
|
||||
options: options
|
||||
options: <Partial<Options>>options
|
||||
});
|
||||
|
||||
const newRequest = {
|
||||
@@ -170,7 +171,7 @@ export class OllamaChat extends ChatCommand {
|
||||
try {
|
||||
await bot.editMessageText({
|
||||
chat_id: chatId,
|
||||
message_id: waitMessage.message_id,
|
||||
message_id: <number>waitMessage?.message_id,
|
||||
text: escapeMarkdownV2Text(text),
|
||||
parse_mode: "MarkdownV2",
|
||||
reply_markup: cancelMarkup
|
||||
@@ -178,9 +179,11 @@ export class OllamaChat extends ChatCommand {
|
||||
|
||||
console.log("editMessageText", text);
|
||||
|
||||
waitMessage.reply_to_message = msg;
|
||||
waitMessage.text = text;
|
||||
await MessageStore.put(waitMessage);
|
||||
if (waitMessage) {
|
||||
waitMessage.reply_to_message = msg;
|
||||
waitMessage.text = text;
|
||||
await MessageStore.put(waitMessage);
|
||||
}
|
||||
} catch (e) {
|
||||
logError(e);
|
||||
}
|
||||
@@ -225,7 +228,7 @@ export class OllamaChat extends ChatCommand {
|
||||
shouldBreak = true;
|
||||
}
|
||||
|
||||
if (getOllamaRequest(uuid).done) {
|
||||
if (getOllamaRequest(uuid)?.done) {
|
||||
shouldBreak = true;
|
||||
}
|
||||
|
||||
@@ -266,17 +269,19 @@ export class OllamaChat extends ChatCommand {
|
||||
}).catch(logError);
|
||||
console.log(`aborted request ${uuid}:`, abortOllamaRequest(uuid));
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.message.toLowerCase().includes("aborted")) return;
|
||||
} catch (e: any) {
|
||||
if (e.message.toLowerCase().includes("aborted")) return;
|
||||
logError(e);
|
||||
|
||||
await bot.editMessageReplyMarkup({
|
||||
chat_id: chatId,
|
||||
message_id: waitMessage.message_id,
|
||||
reply_markup: {inline_keyboard: []}
|
||||
}).catch(logError);
|
||||
if (waitMessage) {
|
||||
await bot.editMessageReplyMarkup({
|
||||
chat_id: chatId,
|
||||
message_id: waitMessage.message_id,
|
||||
reply_markup: {inline_keyboard: []}
|
||||
}).catch(logError);
|
||||
|
||||
logError(error);
|
||||
await oldReplyToMessage(waitMessage, `Произошла ошибка!\n${error.toString()}`).catch(logError);
|
||||
await oldReplyToMessage(waitMessage, `Произошла ошибка!\n${e.toString()}`).catch(logError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,22 +56,24 @@ export class OllamaGetModel extends Command {
|
||||
parse_mode: "Markdown"
|
||||
}).catch(logError);
|
||||
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
logError(e);
|
||||
await replyToMessage({message: msg, text: e.toString()}).catch(logError);
|
||||
}
|
||||
}
|
||||
|
||||
private getModelText(model: string, info: AiModelCapabilities): string {
|
||||
private getModelText(model: string | undefined, info: AiModelCapabilities | null): string {
|
||||
return `model: ${model}\n\n` +
|
||||
`vision: ${boolToEmoji(info.vision?.supported)}\n` +
|
||||
`ocr: ${boolToEmoji(info.ocr?.supported)}\n` +
|
||||
`thinking: ${boolToEmoji(info.thinking?.supported)}\n` +
|
||||
`tools: ${boolToEmoji(info.tools?.supported)}\n` +
|
||||
`audio: ${boolToEmoji(info.audio?.supported)}`;
|
||||
`vision: ${boolToEmoji(info?.vision?.supported)}\n` +
|
||||
`ocr: ${boolToEmoji(info?.ocr?.supported)}\n` +
|
||||
`thinking: ${boolToEmoji(info?.thinking?.supported)}\n` +
|
||||
`tools: ${boolToEmoji(info?.tools?.supported)}\n` +
|
||||
`audio: ${boolToEmoji(info?.audio?.supported)}`;
|
||||
}
|
||||
|
||||
async getModelCapabilities(model: string = Environment.OLLAMA_MODEL): Promise<AiModelCapabilities | null> {
|
||||
async getModelCapabilities(model: string | undefined = Environment.OLLAMA_MODEL): Promise<AiModelCapabilities | null> {
|
||||
if (!model) return null;
|
||||
|
||||
try {
|
||||
const info = await ollama.show({model: model});
|
||||
console.log(info);
|
||||
|
||||
@@ -20,14 +20,16 @@ export class OllamaPrompt extends Command {
|
||||
|
||||
async execute(msg: Message, match?: RegExpExecArray): Promise<void> {
|
||||
console.log("match", match);
|
||||
return this.executeOllama(msg, match?.[3]);
|
||||
return this.executeOllama(msg, match?.[3] || "");
|
||||
}
|
||||
|
||||
async executeOllama(msg: Message, text: string): Promise<void> {
|
||||
if (!text || text.trim().length === 0) return;
|
||||
if (!text || !text.trim().length) return;
|
||||
if (!msg.from) return;
|
||||
|
||||
const chatId = msg.chat.id;
|
||||
|
||||
let waitMessage: Message;
|
||||
let waitMessage: Message | null = null;
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
@@ -45,7 +47,7 @@ export class OllamaPrompt extends Command {
|
||||
});
|
||||
|
||||
const stream = await ollama.generate({
|
||||
model: Environment.OLLAMA_MODEL,
|
||||
model: <string>Environment.OLLAMA_MODEL,
|
||||
stream: true,
|
||||
think: false,
|
||||
prompt: text
|
||||
@@ -83,7 +85,7 @@ export class OllamaPrompt extends Command {
|
||||
try {
|
||||
await bot.editMessageText({
|
||||
chat_id: chatId,
|
||||
message_id: waitMessage.message_id,
|
||||
message_id: <number>waitMessage?.message_id,
|
||||
text: escapeMarkdownV2Text(text),
|
||||
parse_mode: "Markdown",
|
||||
reply_markup: cancelMarkup
|
||||
@@ -91,9 +93,11 @@ export class OllamaPrompt extends Command {
|
||||
|
||||
console.log("editMessageText", text);
|
||||
|
||||
waitMessage.reply_to_message = msg;
|
||||
waitMessage.text = text;
|
||||
await MessageStore.put(waitMessage);
|
||||
if (waitMessage) {
|
||||
waitMessage.reply_to_message = msg;
|
||||
waitMessage.text = text;
|
||||
await MessageStore.put(waitMessage);
|
||||
}
|
||||
} catch (e) {
|
||||
logError(e);
|
||||
}
|
||||
@@ -138,7 +142,7 @@ export class OllamaPrompt extends Command {
|
||||
shouldBreak = true;
|
||||
}
|
||||
|
||||
if (getOllamaRequest(uuid).done) {
|
||||
if (getOllamaRequest(uuid)?.done) {
|
||||
shouldBreak = true;
|
||||
}
|
||||
|
||||
@@ -173,17 +177,19 @@ export class OllamaPrompt extends Command {
|
||||
reply_markup: {inline_keyboard: []}
|
||||
}).catch(logError);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.message.toLowerCase().includes("aborted")) return;
|
||||
} catch (e: any) {
|
||||
if (e.message.toLowerCase().includes("aborted")) return;
|
||||
logError(e);
|
||||
|
||||
await bot.editMessageReplyMarkup({
|
||||
chat_id: chatId,
|
||||
message_id: waitMessage.message_id,
|
||||
reply_markup: {inline_keyboard: []}
|
||||
}).catch(logError);
|
||||
if (waitMessage) {
|
||||
await bot.editMessageReplyMarkup({
|
||||
chat_id: chatId,
|
||||
message_id: waitMessage.message_id,
|
||||
reply_markup: {inline_keyboard: []}
|
||||
}).catch(logError);
|
||||
|
||||
logError(error);
|
||||
await oldReplyToMessage(waitMessage, `Произошла ошибка!\n${error.toString()}`).catch(logError);
|
||||
await oldReplyToMessage(waitMessage, `Произошла ошибка!\n${e.toString()}`).catch(logError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import {Requirement} from "../base/requirement";
|
||||
import {Message} from "typescript-telegram-bot-api";
|
||||
import {bot, ollama} from "../index";
|
||||
import {WebSearchResponse} from "../model/web-search-response";
|
||||
import {oldEditMessageText, logError} from "../util/utils";
|
||||
import {logError, oldEditMessageText} from "../util/utils";
|
||||
import {Environment} from "../common/environment";
|
||||
|
||||
export class OllamaSearch extends Command {
|
||||
@@ -18,6 +18,10 @@ export class OllamaSearch extends Command {
|
||||
|
||||
async execute(msg: Message, match?: RegExpExecArray | null): Promise<void> {
|
||||
console.log("match", match);
|
||||
|
||||
const query = match?.[3] || "";
|
||||
if (!query || !query.length) return;
|
||||
|
||||
const chatId = msg.chat.id;
|
||||
|
||||
try {
|
||||
@@ -31,7 +35,7 @@ export class OllamaSearch extends Command {
|
||||
parse_mode: "Markdown"
|
||||
});
|
||||
|
||||
const results = await ollama.webSearch({query: match?.[3]});
|
||||
const results = await ollama.webSearch({query: query});
|
||||
console.log("results", results);
|
||||
|
||||
let message = "Результаты:\n\n";
|
||||
|
||||
@@ -15,18 +15,19 @@ export class OllamaSetModel extends Command {
|
||||
requirements = Requirements.Build(Requirement.BOT_CREATOR);
|
||||
|
||||
async execute(msg: Message, match?: RegExpExecArray | null): Promise<void> {
|
||||
const newModel = match?.[3];
|
||||
const newModel = match?.[3] || "";
|
||||
if (!newModel || !newModel.length) return;
|
||||
|
||||
try {
|
||||
await ollama.show({model: newModel});
|
||||
|
||||
Environment.setOllamaModel(newModel || Environment.OLLAMA_MODEL);
|
||||
Environment.setOllamaModel(newModel || <string>Environment.OLLAMA_MODEL);
|
||||
|
||||
const text = newModel ? `Выбрана модель "${newModel}"`
|
||||
: `Модель не задана. Будет использоваться стандартная модель "${Environment.OLLAMA_MODEL}".`;
|
||||
|
||||
await replyToMessage({message: msg, text: text}).catch(logError);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
logError(e);
|
||||
await replyToMessage({message: msg, text: e.toString()}).catch(logError);
|
||||
}
|
||||
|
||||
+18
-13
@@ -24,11 +24,11 @@ export class OpenAIChat extends ChatCommand {
|
||||
|
||||
async execute(msg: Message, match?: RegExpExecArray): Promise<void> {
|
||||
console.log("OpenAI Chat: ", match);
|
||||
return this.executeOpenAI(msg, match?.[3]);
|
||||
return this.executeOpenAI(msg, match?.[3] || "");
|
||||
}
|
||||
|
||||
async executeOpenAI(msg: Message, text: string): Promise<void> {
|
||||
if (!text || text.trim().length === 0) return;
|
||||
if (!text || !text.trim().length) return;
|
||||
|
||||
const chatId = msg.chat.id;
|
||||
|
||||
@@ -67,7 +67,7 @@ export class OpenAIChat extends ChatCommand {
|
||||
});
|
||||
}
|
||||
|
||||
let waitMessage: Message;
|
||||
let waitMessage: Message | null = null;
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
@@ -98,7 +98,7 @@ export class OpenAIChat extends ChatCommand {
|
||||
await bot.editMessageText(
|
||||
{
|
||||
chat_id: chatId,
|
||||
message_id: waitMessage.message_id,
|
||||
message_id: <number>waitMessage?.message_id,
|
||||
text: escapeMarkdownV2Text(text),
|
||||
parse_mode: "MarkdownV2"
|
||||
}
|
||||
@@ -106,9 +106,11 @@ export class OpenAIChat extends ChatCommand {
|
||||
|
||||
console.log("editMessageText", text);
|
||||
|
||||
waitMessage.reply_to_message = msg;
|
||||
waitMessage.text = text;
|
||||
await MessageStore.put(waitMessage);
|
||||
if (waitMessage) {
|
||||
waitMessage.reply_to_message = msg;
|
||||
waitMessage.text = text;
|
||||
await MessageStore.put(waitMessage);
|
||||
}
|
||||
},
|
||||
onStop: async () => {
|
||||
}
|
||||
@@ -156,12 +158,15 @@ export class OpenAIChat extends ChatCommand {
|
||||
await replyToMessage({message: waitMessage, text: `⏱️ ${diff}s`});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logError(error);
|
||||
await replyToMessage({
|
||||
message: waitMessage,
|
||||
text: `Произошла ошибка!\n${error.toString()}`
|
||||
}).catch(logError);
|
||||
} catch (e: any) {
|
||||
logError(e);
|
||||
|
||||
if (waitMessage) {
|
||||
await replyToMessage({
|
||||
message: waitMessage,
|
||||
text: `Произошла ошибка!\n${e.toString()}`
|
||||
}).catch(logError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ export class OpenAIGetModel extends Command {
|
||||
try {
|
||||
return {
|
||||
vision: {supported: true},
|
||||
ocr: null,
|
||||
ocr: undefined,
|
||||
thinking: {supported: true},
|
||||
tools: {supported: true},
|
||||
};
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ export class Qr extends Command {
|
||||
},
|
||||
parse_mode: "HTML"
|
||||
});
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
await replyToMessage({
|
||||
message: msg,
|
||||
text: `Не получилось сгенерировать QR: ${e?.message ?? String(e)}`
|
||||
|
||||
@@ -48,6 +48,7 @@ export class Quote extends Command {
|
||||
async execute(msg: Message): Promise<void> {
|
||||
const chatId = msg.chat.id;
|
||||
const reply = msg.reply_to_message;
|
||||
if (!reply) return;
|
||||
|
||||
try {
|
||||
const quoteRaw = (msg.quote?.text ?? reply.text ?? reply.caption ?? "").trim();
|
||||
@@ -97,7 +98,9 @@ function twemojiUrl(emoji: string) {
|
||||
return `https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/${code}.png`;
|
||||
}
|
||||
|
||||
async function loadEmoji(emoji: string): Promise<CanvasImage> {
|
||||
async function loadEmoji(emoji: string | undefined): Promise<CanvasImage | null> {
|
||||
if (!emoji) return null;
|
||||
|
||||
const downloadAndCache = async (url: string): Promise<Image> => {
|
||||
const res = await axios.get<ArrayBuffer>(url, {responseType: "arraybuffer"});
|
||||
const img = await loadImage(Buffer.from(res.data));
|
||||
@@ -491,7 +494,7 @@ async function drawLine(ctx: SKRSContext2D, line: Segment[], x: number, baseline
|
||||
try {
|
||||
const img = await loadEmoji(seg.v);
|
||||
const y = baselineY - emojiSize + Math.round(fontSize * 0.2);
|
||||
ctx.drawImage(img, cx, y, emojiSize, emojiSize);
|
||||
ctx.drawImage(<Image>img, cx, y, emojiSize, emojiSize);
|
||||
} catch (e) {
|
||||
logError(e);
|
||||
ctx.fillText(seg.v, cx, baselineY);
|
||||
@@ -506,7 +509,7 @@ async function drawLine(ctx: SKRSContext2D, line: Segment[], x: number, baseline
|
||||
} else {
|
||||
const img = await loadEmoji("😥");
|
||||
const y = baselineY - emojiSize + Math.round(fontSize * 0.2);
|
||||
ctx.drawImage(img, cx, y, emojiSize, emojiSize);
|
||||
ctx.drawImage(<Image>img, cx, y, emojiSize, emojiSize);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("Failed to draw custom emoji:", e);
|
||||
@@ -514,7 +517,7 @@ async function drawLine(ctx: SKRSContext2D, line: Segment[], x: number, baseline
|
||||
try {
|
||||
const img = await loadEmoji("😥");
|
||||
const y = baselineY - emojiSize + Math.round(fontSize * 0.2);
|
||||
ctx.drawImage(img, cx, y, emojiSize, emojiSize);
|
||||
ctx.drawImage(<Image>img, cx, y, emojiSize, emojiSize);
|
||||
} catch (e) {
|
||||
logError(e);
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@ export class RandomInt extends Command {
|
||||
description = "Ranged random integer from parameters";
|
||||
|
||||
async execute(msg: Message) {
|
||||
// TODO: 01/05/2026, Danil Nikolaev: improve
|
||||
if (!msg.text) return;
|
||||
|
||||
const split = msg.text.split(" ");
|
||||
const min = parseInt(split[1]);
|
||||
const max = parseInt(split[2]);
|
||||
|
||||
@@ -9,6 +9,9 @@ export class RandomString extends Command {
|
||||
description = "literally random string (up to 4096 symbols)";
|
||||
|
||||
async execute(msg: Message) {
|
||||
// TODO: 01/05/2026, Danil Nikolaev: improve
|
||||
if (!msg.text) return;
|
||||
|
||||
const split = msg.text.split(" ");
|
||||
const l = parseInt(split.length > 1 ? split[1] : "1");
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@ export class Start extends Command {
|
||||
description = "Start the bot";
|
||||
|
||||
async execute(msg: Message): Promise<void> {
|
||||
await commands.find(e => e instanceof Help).execute(msg);
|
||||
await commands.find(e => e instanceof Help)?.execute(msg);
|
||||
}
|
||||
}
|
||||
@@ -81,12 +81,14 @@ export class Transliteration extends Command {
|
||||
description = "Transliteration EN <--> RU";
|
||||
|
||||
async execute(msg: Message): Promise<void> {
|
||||
if (!msg.text && !msg.caption) return;
|
||||
|
||||
let text: string = "";
|
||||
|
||||
if (msg.reply_to_message) {
|
||||
text = (msg.reply_to_message.text || msg.reply_to_message.caption || "");
|
||||
} else {
|
||||
const split = (msg.text || msg.caption).split("/tr ");
|
||||
const split = (<string>(msg.text || msg.caption)).split("/tr ");
|
||||
if (split.length > 1) {
|
||||
text = split[1].trim();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export class Unban extends Command {
|
||||
);
|
||||
|
||||
async execute(msg: Message) {
|
||||
if (!msg.reply_to_message) return;
|
||||
if (!msg.reply_to_message || !msg.reply_to_message.from) return;
|
||||
|
||||
const user = msg.reply_to_message.from;
|
||||
const userId = user.id;
|
||||
@@ -34,7 +34,7 @@ export class Unban extends Command {
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.from.id !== Environment.CREATOR_ID && Environment.ADMIN_IDS.has(userId)) {
|
||||
if (msg.from?.id !== Environment.CREATOR_ID && Environment.ADMIN_IDS.has(userId)) {
|
||||
await oldReplyToMessage(msg, "Админимтраторы бота и так не в бане.").catch(logError);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ export class Unignore extends Command {
|
||||
);
|
||||
|
||||
async execute(msg: Message) {
|
||||
if (!msg.reply_to_message) return;
|
||||
if (!msg.reply_to_message || !msg.reply_to_message.from) return;
|
||||
|
||||
const id = msg.reply_to_message.from.id;
|
||||
const text = fullName(msg.reply_to_message.from);
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import {Command} from "../base/command";
|
||||
import {Message} from "typescript-telegram-bot-api";
|
||||
import {editMessageText, logError, replyToMessage} from "../util/utils";
|
||||
import {bot, botUser} from "../index";
|
||||
import {DownloadOptions, downloadVideoFromYouTube, getYouTubeVideoId} from "../util/ytdl";
|
||||
import {Environment} from "../common/environment";
|
||||
import {TryAgain} from "../callback_commands/try-again";
|
||||
|
||||
export class YouTubeDownload extends Command {
|
||||
command = ["ytdl", "youtube"];
|
||||
argsMode = "required" as const;
|
||||
|
||||
async execute(msg: Message, match?: RegExpExecArray): Promise<void> {
|
||||
const url = match?.[3];
|
||||
return this.downloadYouTubeVideo(msg, {url: url});
|
||||
}
|
||||
|
||||
async downloadYouTubeVideo(msg: Message, options: DownloadOptions): Promise<void> {
|
||||
// TODO: 02.03.2026, Danil Nikolaev: add check for date
|
||||
let waitMessage: Message | null = (msg.from.id === botUser.id) ? msg : null;
|
||||
const videoId = "videoId" in options ? options.videoId : getYouTubeVideoId(options.url);
|
||||
|
||||
try {
|
||||
if (!waitMessage) {
|
||||
waitMessage = await replyToMessage({message: msg, text: "⏳ Скачиваю видео..."});
|
||||
} else {
|
||||
await editMessageText({message: msg, text: "⏳ Скачиваю видео..."});
|
||||
}
|
||||
|
||||
const {time, exists, buffer} = await downloadVideoFromYouTube({videoId: videoId});
|
||||
if (buffer) {
|
||||
const start = Date.now();
|
||||
waitMessage = await bot.editMessageMedia({
|
||||
chat_id: msg.chat.id,
|
||||
message_id: waitMessage.message_id,
|
||||
media: {
|
||||
type: "video",
|
||||
media: buffer
|
||||
}
|
||||
}) as Message;
|
||||
|
||||
const diff = Date.now() - start;
|
||||
waitMessage = await bot.editMessageCaption({
|
||||
chat_id: msg.chat.id,
|
||||
message_id: waitMessage.message_id,
|
||||
caption: "✅ Видео" + (exists ? " загружено из кэша" : " успешно скачано") + " за " + (time + diff) + "мс",
|
||||
}) as Message;
|
||||
}
|
||||
} catch (e) {
|
||||
logError(e);
|
||||
|
||||
if (waitMessage && "text" in waitMessage) {
|
||||
await bot.editMessageText({
|
||||
chat_id: msg.chat.id,
|
||||
message_id: waitMessage.message_id,
|
||||
text: Environment.errorText,
|
||||
reply_markup: {
|
||||
inline_keyboard: [[
|
||||
TryAgain.withData("/ytdl " + videoId).asButton()
|
||||
]]
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user