From 0f55f5f52e84fd5cdedb448d408dfa3c69c5fe5f Mon Sep 17 00:00:00 2001 From: Andrew Lee Date: Thu, 20 Mar 2025 16:20:59 -0400 Subject: Modularized LLM chatbot; Added back eval --- bot/src/commands/about.js | 4 +++- bot/src/commands/timer.js | 2 +- bot/src/events/MessageCreate.js | 39 ++++++------------------------- bot/src/plugins/chatbot.js | 35 +++++++++++++++++++++++++++- bot/src/plugins/eval.js | 51 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 95 insertions(+), 36 deletions(-) diff --git a/bot/src/commands/about.js b/bot/src/commands/about.js index 311200e..22b3441 100644 --- a/bot/src/commands/about.js +++ b/bot/src/commands/about.js @@ -21,7 +21,9 @@ export default { { name: 'About AleeBot', value: 'AleeBot is an all-in-one bot that\'s made from the Discord.JS API!' }, { name: 'Servers', value: `${interaction.client.guilds.cache.size}` }, { name: 'License', value: 'GNU General Public License v3.0' }, - { name: 'Contributors', value: '- <@297201585090723841> (Uptime command from 2.x)' } + { name: 'Contributors', value: + '- <@297201585090723841> (Uptime command from 2.x)\n' + + '- <@236279900728721409> (Eval command from 2.x)' } ) .setFooter({ text: '© Copyright 2017-2025 Andrew Lee & contributors' }) .setColor(abEmbedColour); diff --git a/bot/src/commands/timer.js b/bot/src/commands/timer.js index 3b3807e..68a113c 100644 --- a/bot/src/commands/timer.js +++ b/bot/src/commands/timer.js @@ -41,7 +41,7 @@ export default { setTimeout(async function(){ if (interaction.guild) { let remindChannel = interaction.client.channels.cache.get(interaction.channel.id); - if (!remindChannel) return console.error('Unknown channel.'); + if (!remindChannel) return; return await remindChannel.send({ content: `${interaction.user}, You have been reminded.${message ? '\n\n' + content : ''}` }); } else { return await interaction.user.send({ content: `You have been reminded.${message ? '\n\n' + content : ''}` }); diff --git a/bot/src/events/MessageCreate.js b/bot/src/events/MessageCreate.js index 406539e..23aaf87 100644 --- a/bot/src/events/MessageCreate.js +++ b/bot/src/events/MessageCreate.js @@ -1,7 +1,6 @@ -import {AttachmentBuilder, Events} from 'discord.js'; -import { ollama } from '../utils/ollama.js'; -import { ollamaGlobal, ollamaModel } from '../storage/consts.js'; -import { guildSettings } from '../models/guild-settings.js'; +import { Events } from 'discord.js'; +import { ChatBot } from '../plugins/chatbot.js'; +import { Evaluation } from '../plugins/eval.js'; export default { name: Events.MessageCreate, @@ -10,37 +9,13 @@ export default { if (msg.author.bot) return; if (!msg.guild) return; - const guildSetting = await guildSettings.findOne({ where: { guildID: msg.guild.id } }); - const args = msg.content.slice(`${msg.client.user}`.length).trim(); - // TODO: Check if the person mentions a specific command that executes eval, then start a message collection. - if (msg.mentions.has(msg.client.user)) { - if (!guildSetting.ollamaEnabled) return; - if (!ollamaGlobal) return msg.reply('Sorry, the LLM chatbot feature has been turned off.'); - if (!args) return msg.reply('Sorry? What was that?'); - - try { - const loadingMessage = await msg.reply('Thinking...'); - - const response = await ollama.chat({ - model: ollamaModel, - messages: [{ role: 'user', content: args }], - }); - - let content = response.message.content; - - if (content.length > 2000) { - const attachment = new AttachmentBuilder(Buffer.from(content, 'utf-8'), { name: 'output.txt' }); - return await loadingMessage.edit({ files: [attachment] }); - } else { - return await loadingMessage.edit({ content }); - } - - } catch (err) { - console.error(err); - await msg.reply(`Something went wrong. [Submit an issue at the AleeBot repository.]()\nMessage:\n\`\`\`${err.stack}\`\`\``); + if (args === 'execute') { + await Evaluation(msg); + } else { + await ChatBot(msg, args); } } } diff --git a/bot/src/plugins/chatbot.js b/bot/src/plugins/chatbot.js index f4095a2..3da7421 100644 --- a/bot/src/plugins/chatbot.js +++ b/bot/src/plugins/chatbot.js @@ -1 +1,34 @@ -// add llm feature here +import { ollamaGlobal, ollamaModel } from '../storage/consts.js'; +import { ollama } from '../utils/ollama.js'; +import { AttachmentBuilder } from 'discord.js'; +import { guildSettings } from '../models/guild-settings.js'; + +export async function ChatBot(msg, args) { + const guildSetting = await guildSettings.findOne({ where: { guildID: msg.guild.id } }); + + if (!guildSetting.ollamaEnabled) return; + if (!ollamaGlobal) return msg.reply('Sorry, the LLM chatbot feature has been turned off.'); + if (!args) return msg.reply('Sorry? What was that?'); + + try { + const loadingMessage = await msg.reply('Thinking...'); + + const response = await ollama.chat({ + model: ollamaModel, + messages: [{ role: 'user', content: args }], + }); + + let content = response.message.content; + + if (content.length > 2000) { + const attachment = new AttachmentBuilder(Buffer.from(content, 'utf-8'), { name: 'output.txt' }); + return await loadingMessage.edit({ files: [attachment] }); + } else { + return await loadingMessage.edit({ content }); + } + + } catch (err) { + console.error(err); + await msg.reply(`Something went wrong. [Submit an issue at the AleeBot repository.]()\nMessage:\n\`\`\`${err.stack}\`\`\``); + } +} diff --git a/bot/src/plugins/eval.js b/bot/src/plugins/eval.js index 47b3988..c667dca 100644 --- a/bot/src/plugins/eval.js +++ b/bot/src/plugins/eval.js @@ -1,3 +1,52 @@ -export async function evaluation() { +import { inspect } from 'util'; +export async function Evaluation(msg) { + if (!['242775871059001344'].includes(msg.author.id)) return await msg.reply('Nope! You need the person who created this bot to use this command.'); + await msg.reply('You have entered evaluation mode. Enter the code for AleeBot to evaluate.\nType in `exit` to exit evaluation mode.'); + + let evaled; + let remove; + + const filter = (i) => i.author.id === msg.author.id; + + const collector = msg.channel.createMessageCollector({ + filter, + time: 1000 * 600 + }); + + collector.on('collect', async (msg) => { + if (msg.content.toLowerCase() === 'exit') { + return collector.stop(); + } + + try { + remove = (text) => { + if (typeof(text) === 'string') { + return text.replace(/`/g, '`' + String.fromCharCode(8203)).replace(/@/g, '@' + String.fromCharCode(8203)); + } else { + return text; + } + }; + + evaled = eval(msg.content); + + if (typeof evaled !== 'string') { + evaled = inspect(evaled); + } + + } catch (err) { + return await msg.reply(`**Error:**\n\`\`\`\n${err.stack}\n\`\`\``); + } + + try { + return await msg.reply(`**Output:**\n\`\`\`js\n${remove(evaled)}\n\`\`\``); + } catch (err) { + return await msg.reply(`**Error:**\n\`\`\`\n${err.stack}\n\`\`\``); + } + + }); + + collector.on('end', async () => { + return await msg.reply('Exiting evaluation mode.'); + }); } -- cgit v1.2.3