diff --git a/bot/commands/admin/getId.js b/bot/commands/admin/getId.js index 241b897..3809e28 100644 --- a/bot/commands/admin/getId.js +++ b/bot/commands/admin/getId.js @@ -10,7 +10,7 @@ export const getId = bot => { parse_mode: 'HTML', reply_to_message_id: msgId } - msg['ctx'] = INITIAL_SESSION + try { await bot.sendMessage( chatId, diff --git a/bot/commands/admin/refundTokensIfError.js b/bot/commands/admin/refundTokensIfError.js index 899bbc7..9eec427 100644 --- a/bot/commands/admin/refundTokensIfError.js +++ b/bot/commands/admin/refundTokensIfError.js @@ -14,7 +14,7 @@ export const refundTokensIfError = bot => { parse_mode: 'HTML', reply_to_message_id: msgId } - msg['ctx'] = INITIAL_SESSION + try { const errors = await db.convertor_requests.findAll({ where: { [Op.or]: [{ status: 'work' }, { status: 'error' }] } }) diff --git a/bot/commands/admin/setQuizModeForSubs.js b/bot/commands/admin/setQuizModeForSubs.js index a236ab5..950596f 100644 --- a/bot/commands/admin/setQuizModeForSubs.js +++ b/bot/commands/admin/setQuizModeForSubs.js @@ -15,7 +15,7 @@ export const setQuizModeForSubs = (bot) => { const options = { parse_mode: 'HTML' } - msg['ctx'] = INITIAL_SESSION + try { await db.subscriber.update( { quiz_subs_available, quiz_token_available }, diff --git a/bot/commands/keyboard/chat_gpt.js b/bot/commands/keyboard/chat_gpt.js index cab76d5..7288e48 100644 --- a/bot/commands/keyboard/chat_gpt.js +++ b/bot/commands/keyboard/chat_gpt.js @@ -99,7 +99,7 @@ export const keyboardChatGPT = async (bot, msg) => { const options = { parse_mode: 'HTML', reply_to_message_id: msgId, - reply_markup: await createStartKeyboardForReplyMarkup(msg) + reply_markup: createStartKeyboardForReplyMarkup(msg) } try { db.subscriber.findOne({ diff --git a/bot/commands/keyboard/converter.js b/bot/commands/keyboard/converter.js index 9c58540..f4b406b 100644 --- a/bot/commands/keyboard/converter.js +++ b/bot/commands/keyboard/converter.js @@ -17,7 +17,6 @@ export const keyboardConverter = async (bot, msg) => { chat_id: msg.chat.id, message_id: message_id, parse_mode: 'HTML', - reply_markup: await createStartKeyboardForReplyMarkup(msg) }).catch(() => { return true }) diff --git a/bot/commands/keyboard/dalle.js b/bot/commands/keyboard/dalle.js index b274d34..9034ff4 100644 --- a/bot/commands/keyboard/dalle.js +++ b/bot/commands/keyboard/dalle.js @@ -65,7 +65,6 @@ export const keyboardDalle = async (bot, msg) => { const options = { parse_mode: 'HTML', reply_to_message_id: msgId, - reply_markup: await createStartKeyboardForReplyMarkup(msg) } try { db.subscriber.findOne({ diff --git a/bot/commands/keyboard/help.js b/bot/commands/keyboard/help.js index dfb918a..904a376 100644 --- a/bot/commands/keyboard/help.js +++ b/bot/commands/keyboard/help.js @@ -1,10 +1,13 @@ +import { createStartKeyboardForReplyMarkup } from '../../utils/createStartKeyboard.js' + export const keyboardHelp = async (bot, msg, t) => { let accountMessage const { id: chatId } = msg.chat const msgId = msg.message_id const options = { parse_mode: 'HTML', - reply_to_message_id: msgId + reply_to_message_id: msgId, + reply_markup: createStartKeyboardForReplyMarkup(msg) } try { diff --git a/bot/commands/keyboard/my_account.js b/bot/commands/keyboard/my_account.js index 0ab8042..f2e98fa 100644 --- a/bot/commands/keyboard/my_account.js +++ b/bot/commands/keyboard/my_account.js @@ -31,7 +31,7 @@ export const keyboardMyAccount = async (bot, msg, prevMessageForEdit, prevLevel, parse_mode: 'HTML', reply_to_message_id: msgId, disable_web_page_preview: true, - reply_markup: await createStartKeyboardForReplyMarkup(msg) + reply_markup: createStartKeyboardForReplyMarkup(msg) } try { const inlineKeyboard = [ @@ -42,7 +42,6 @@ export const keyboardMyAccount = async (bot, msg, prevMessageForEdit, prevLevel, const prevKeyboard = [{ text: t('prev_component'), callback_data: `prev_component_${msgId}` }] // только если prevLevel const referralLevel = await referralLevelCreator(msg, generalOptions, msgId, 'my_account') const eventEmitter = new events.EventEmitter() - msg['ctx'] = INITIAL_SESSION if (prevLevel) inlineKeyboard.push(prevKeyboard) diff --git a/bot/commands/modes/chatGPT.js b/bot/commands/modes/chatGPT.js index 24384c4..53319a3 100644 --- a/bot/commands/modes/chatGPT.js +++ b/bot/commands/modes/chatGPT.js @@ -9,11 +9,19 @@ import { createFullName } from '../../utils/createFullName.js' import { ct } from '../../utils/createTranslate.js' import { writingOffTokens } from '../../utils/checkTokens.js' +export async function cleanContext (chatID) { + await db.subscriber.update( + { comment: null }, + { where: { chat_id: chatID } } + ) +} + export const modeChatGPT = async (bot, msg, qweryOptions) => { const t = await ct(msg) let res let modeGPT let newMessage + let ctx const { id: userId } = msg.from const { id: chatID } = msg.chat const msgId = msg.message_id @@ -23,17 +31,20 @@ export const modeChatGPT = async (bot, msg, qweryOptions) => { } try { - db.subscriber.findOne({ + await db.subscriber.findOne({ where: { chat_id: chatID, user_id: msg.from.id } }).then(async response => { modeGPT = response.dataValues.modeGPT + ctx = await JSON.parse(response.dataValues.comment) }) // TODO: Запоминать контекст беседы пользователя или всегда начинать новый чат - msg.ctx ??= INITIAL_SESSION + ctx ??= INITIAL_SESSION + + console.log('🔺ctx', ctx.messages.length) res = await spinnerOn(bot, chatID, null, 'chatGPT') let message = await bot.sendMessage(chatID, '...').catch(() => { @@ -47,7 +58,7 @@ export const modeChatGPT = async (bot, msg, qweryOptions) => { if (modeGPT === 'assistant') { newMessage = msg.text ?? msg.sticker?.emoji - msg.ctx = INITIAL_SESSION + await cleanContext(chatID) } else if (msg.text) { newMessage = await t(x?.prompt_start) newMessage = newMessage + '\n\n' + msg.text @@ -55,12 +66,12 @@ export const modeChatGPT = async (bot, msg, qweryOptions) => { newMessage = msg.sticker.emoji } - await msg?.ctx.messages.push({ + ctx.messages.push({ role: openAi.roles.User, content: newMessage }) - const response = await openAi.chat(msg?.ctx.messages, bot, message, chatID, x.parse_mode) + const response = await openAi.chat(ctx.messages, bot, message, chatID, x.parse_mode) const textSum = (response + newMessage) @@ -70,11 +81,16 @@ export const modeChatGPT = async (bot, msg, qweryOptions) => { throw new Error('Something went wrong please try again.') } - msg?.ctx.messages.push({ + ctx.messages.push({ role: openAi.roles.Assistant, content: response }) + await db.subscriber.update( + { comment: JSON.stringify(ctx) }, + { where: { chat_id: chatID } } + ) + await spinnerOff(bot, chatID, res) db.history.update({ diff --git a/bot/commands/onMessageTextDefault.js b/bot/commands/onMessageTextDefault.js index 81a24df..c108c03 100644 --- a/bot/commands/onMessageTextDefault.js +++ b/bot/commands/onMessageTextDefault.js @@ -1,8 +1,11 @@ -import { modeChatGPT } from './modes/chatGPT.js' +import { cleanContext, modeChatGPT } from './modes/chatGPT.js' import events from 'events' import { db } from '../db/index.js' import { removeQueryFromPrevMessage } from './hoc/removeQueryFromPrevMsg.js' import { modesChatGPT } from '../constants/modes.js' +import { INITIAL_SESSION } from '../constants/index.js' +import { autoRemoveMessage } from './hoc/autoRemoveMessage.js' +import { keyboardChatGPT } from './keyboard/chat_gpt.js' export const onMessageTextDefault = async (bot, msg, match, sudoUser, t) => { const { id: chatID } = msg.chat @@ -24,8 +27,8 @@ export const onMessageTextDefault = async (bot, msg, match, sudoUser, t) => { ...optionsGeneral, reply_markup: { inline_keyboard: [ - [{ text: t('btn_new_chat'), callback_data: 'create_new_chat' }, - { text: t('btn_change_mode'), callback_data: 'change_chat_mode' }] + [{ text: t('btn_new_chat'), callback_data: `create_new_chat${msgId}` }, + { text: t('btn_change_mode'), callback_data: `change_chat_mode${msgId}` }] ] } } @@ -41,14 +44,19 @@ export const onMessageTextDefault = async (bot, msg, match, sudoUser, t) => { const eventEmitter = new events.EventEmitter() - eventEmitter.on('change_chat_mode', async function() { + eventEmitter.on(`create_new_chat${msgId}`, async function() { + await autoRemoveMessage('✅ ' + t('btn_new_chat'), bot, chatID, {},10000) + await cleanContext(chatID) + }) + + eventEmitter.on(`change_chat_mode${msgId}`, async function() { await bot.editMessageText( firstMessage.text, { message_id: firstMessage.message_id, chat_id: chatID, reply_markup: { - inline_keyboard: modesChatGPT.map((mode) => [{ text: mode.name, callback_data: mode.code }]) + inline_keyboard: modesChatGPT.map((mode) => [{ text: t(mode.name), callback_data: mode.code }]) } } ).catch((err) => { @@ -76,7 +84,8 @@ export const onMessageTextDefault = async (bot, msg, match, sudoUser, t) => { await db.subscriber.update( { modeGPT: modesChatGPT[i].code }, { where: { chat_id: chatID } } - ).then(res => { + ).then(async res => { + await removeQueryFromPrevMessage(bot, msg.chat.id, firstMessage) // bot.deleteMessage(chatID, firstMessage.message_id).catch(err => console.error(err)) firstMessage = modeChatGPT(bot, msg, { message_id: firstMessage.message_id, diff --git a/bot/commands/start.js b/bot/commands/start.js index 704b8b1..bf4cb28 100644 --- a/bot/commands/start.js +++ b/bot/commands/start.js @@ -15,9 +15,9 @@ export const startBot = bot => { const options = { parse_mode: 'HTML', reply_to_message_id: msgId, - reply_markup: await createStartKeyboardForReplyMarkup(msg) + reply_markup: createStartKeyboardForReplyMarkup(msg) } - msg['ctx'] = INITIAL_SESSION + try { await bot.sendMessage( chatId, diff --git a/bot/db/models/subscriber.model.js b/bot/db/models/subscriber.model.js index 8bf757a..ea92cfd 100644 --- a/bot/db/models/subscriber.model.js +++ b/bot/db/models/subscriber.model.js @@ -58,16 +58,16 @@ export default (sequelize, DataTypes) => { type: DataTypes.DOUBLE, defaultValue: 0 }, - GPT_count: { - type: DataTypes.DOUBLE, - defaultValue: 0 + GPT_model: { + type: DataTypes.STRING, + defaultValue: 'gpt-3.5-turbo' }, FILES_count: { type: DataTypes.DOUBLE, defaultValue: 0 }, comment: { - type: DataTypes.STRING, + type: DataTypes.TEXT, }, tags: { type: DataTypes.STRING, diff --git a/bot/utils/checkTokens.js b/bot/utils/checkTokens.js index 43413a5..27102a3 100644 --- a/bot/utils/checkTokens.js +++ b/bot/utils/checkTokens.js @@ -17,7 +17,7 @@ export const checkTokens = async (typeRequest, userID, text = '') => { case REQUEST_TYPES.GPT: case REQUEST_TYPES.TTS: // умножение на коэффицент - countTokens = await calculationOfNumberOfTokens(text, REQUEST_TYPES_COST[typeRequest], 'gpt-3.5-turbo') + countTokens = await calculationOfNumberOfTokens(text, REQUEST_TYPES_COST[typeRequest]) return isTokens(userID, settings, countTokens, typeRequest) case REQUEST_TYPES.DALLE: case REQUEST_TYPES.MIDJOURNEY: @@ -33,13 +33,14 @@ export const checkTokens = async (typeRequest, userID, text = '') => { export async function writingOffTokens(bot, msg, type, prompt = '') { const t = await ct(msg) const {price} = await checkTokens(type, msg.from.id, prompt) + const { GPT_model } = await db.subscriber.findOne({ where: { user_id: msg.from.id } }) await db.subscriber.update( { tokens: Sequelize.literal(`tokens - ${price}`) }, { where: { chat_id: msg.from.id } } ) - await autoRemoveMessage(t('msg:writing-off-tokens', {price}), bot, msg.from.id) + await autoRemoveMessage(t('msg:writing-off-tokens', {price}) + ` ${GPT_model}`, bot, msg.from.id) } async function calculationOfNumberOfTokens(text, type = REQUEST_TYPES_COST.GPT, model = 'gpt-3.5-turbo') { diff --git a/bot/utils/createStartKeyboard.js b/bot/utils/createStartKeyboard.js index 7c7428f..1e80850 100644 --- a/bot/utils/createStartKeyboard.js +++ b/bot/utils/createStartKeyboard.js @@ -14,13 +14,13 @@ export const createStartKeyboardForReplyMarkup = async (msg) => { { text: COMMAND_MIDJOURNEY } ], [ - { text: t('keyboard_tts') }, - { text: t('keyboard_convertor') } + { text: await t('keyboard_tts') }, + { text: await t('keyboard_convertor') } ], [ - { text: t('keyboard_quiz') }, - { text: t('keyboard_acc') }, - { text: t('keyboard_help') } + { text: await t('keyboard_quiz') }, + { text:await t('keyboard_acc') }, + { text:await t('keyboard_help') } ] ] } diff --git a/bot/utils/openAi.js b/bot/utils/openAi.js index 6bf4fab..fa3e012 100644 --- a/bot/utils/openAi.js +++ b/bot/utils/openAi.js @@ -3,6 +3,7 @@ import { OpenAI as OpenAIApi } from 'openai' import dotenv from 'dotenv' import path from 'path' import fs from 'fs' +import { db } from '../db/index.js' dotenv.config({ path: '../.env' }) @@ -41,7 +42,6 @@ export class OpenAI { // TODO: BILL: Если куплена подписка и есть доступные запросы из лимитов ставить 4 // chatGPTVersion = 'gpt-4' - chatGPTVersion = 'gpt-3.5-turbo' constructor(filepath) { this.openai = new OpenAIApi({ @@ -51,11 +51,21 @@ export class OpenAI { } async chat(messages, bot, editMessage, chatId, parceMode) { + const { dataValues: { GPT_model } } = await db.subscriber.findOne({ + where: { + user_id: chatId + } + }) + + if (!GPT_model) + return 'Error: 403' + const response = await this.openai.chat.completions.create({ - model: this.chatGPTVersion, + model: GPT_model, messages, stream: true }) + let answer = '' let prevAnswer = '' for await (const chunk of response) {