diff --git a/bots/discord/commands/trainMessage.js b/bots/discord/commands/trainMessage.js index 02d9c5e..1722517 100644 --- a/bots/discord/commands/trainMessage.js +++ b/bots/discord/commands/trainMessage.js @@ -1,9 +1,6 @@ import { ContextMenuCommandBuilder, - ApplicationCommandType, - ActionRowBuilder, - StringSelectMenuBuilder, - ComponentType + ApplicationCommandType } from 'discord.js'; export default { @@ -20,40 +17,6 @@ export default { content: 'You don\'t have the permission to do this.', ephemeral: true }); - const options = []; - - for (const { label } of config.responses) { - options.push({ - label: label, - description: `The ${label} label.`, - value: label.toLowerCase() - }); - } - - const row = new ActionRowBuilder().addComponents( - new StringSelectMenuBuilder() - .setCustomId('select') - .setPlaceholder('Nothing selected') - .addOptions(options) - ); - const reply = await interaction.reply({ - content: 'Please select the corresponding label to train the bot.', - components: [row], - ephemeral: true - }); - - const collector = reply.createMessageComponentCollector({ - componentType: ComponentType.StringSelect, - time: 15000 - }); - - collector.on('collect', (i) => { - helper.sendTrainData( - interaction.targetMessage.content.toLowerCase(), - i.values[0].toUpperCase() - ); - - i.reply({ content: 'Sent train data to server.', ephemeral: true }); - }); + } }; diff --git a/bots/discord/events/helper/aiResponse.js b/bots/discord/events/helper/aiResponse.js index b60d6fc..c51ec1f 100644 --- a/bots/discord/events/helper/aiResponse.js +++ b/bots/discord/events/helper/aiResponse.js @@ -1,9 +1,10 @@ -import { EmbedBuilder } from 'discord.js'; +import { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js'; +import trainAISelectMenu from '../../utils/trainAISelectMenu.js'; export default { name: 'aiResponse', once: false, - async execute(client, config, aiRes) { + async execute(client, config, helper, aiRes) { if (!aiRes.response) return; if (!aiRes.response[0]) return; @@ -26,9 +27,11 @@ export default { const intent = aiRes.response.reduce((a, b) => a.confidence > b.confidence ? a : b ); + const response = config.responses.find( (res) => res.label === intent.name ); + if (response.threshold > intent.confidence) return; if (!response.reply) return; @@ -38,8 +41,33 @@ export default { .setColor(14908858) .setFooter({ text: `Confidence: ${intent.confidence}` }); - message.reply({ embeds: [embed] }); + const feedbackRow = new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setCustomId('fb-like') + .setEmoji('👍') + .setStyle(ButtonStyle.Success), + new ButtonBuilder() + .setCustomId('fb-dislike') + .setEmoji('👎') + .setStyle(ButtonStyle.Danger) + ); + const reply = await message.reply({ embeds: [embed], components: [feedbackRow] }); + const filter = (i) => i.member.roles.highest.comparePositionTo( + i.member.guild.roles.cache.get(config.discord.trainRole) + ) < 0 + + const collector = reply.createMessageComponentCollector({ filter, time: 15_000 }); + collector.on('collect', (i) => { + if (i.customId == 'fb-like') { + // We train it using the label the AI gave. + helper.sendTrainData(message.content); + i.reply({ ephemeral: true, content: 'Sent train data to server.' }); + } else { + // We ask the trainer to train it using the select menu. + trainAISelectMenu(i, config, helper); + } + }) return; } catch (e) { console.log(e); diff --git a/bots/discord/index.js b/bots/discord/index.js index 2375008..886b744 100644 --- a/bots/discord/index.js +++ b/bots/discord/index.js @@ -72,11 +72,11 @@ export default async () => { const event = (await import(`file://${filePath}`)).default; if (event.once) { helper.once(event.name, (...args) => - event.execute(client, config, ...args) + event.execute(client, config, helper, ...args) ); } else { helper.on(event.name, (...args) => - event.execute(client, config, ...args) + event.execute(client, config, helper, ...args) ); } } diff --git a/bots/discord/utils/trainAISelectMenu.js b/bots/discord/utils/trainAISelectMenu.js new file mode 100644 index 0000000..c858bbc --- /dev/null +++ b/bots/discord/utils/trainAISelectMenu.js @@ -0,0 +1,43 @@ +import { + ActionRowBuilder, + StringSelectMenuBuilder, + ComponentType +} from 'discord.js'; + +export default async function trainAISelectMenu(interaction, config, helper) { + const options = []; + + for (const { label } of config.responses) { + options.push({ + label: label, + description: `The ${label} label.`, + value: label.toLowerCase() + }); + } + + const row = new ActionRowBuilder().addComponents( + new StringSelectMenuBuilder() + .setCustomId('select') + .setPlaceholder('Nothing selected') + .addOptions(options) + ); + const reply = await interaction.reply({ + content: 'Please select the corresponding label to train the bot.', + components: [row], + ephemeral: true + }); + + const collector = reply.createMessageComponentCollector({ + componentType: ComponentType.StringSelect, + time: 15000 + }); + + collector.on('collect', (i) => { + helper.sendTrainData( + interaction.targetMessage.content.toLowerCase(), + i.values[0].toUpperCase() + ); + + i.reply({ content: 'Sent train data to server.', ephemeral: true }); + }); +} \ No newline at end of file diff --git a/bots/telegram/events/helper/aiResponse.js b/bots/telegram/events/helper/aiResponse.js index 0c5f003..fe0de5f 100644 --- a/bots/telegram/events/helper/aiResponse.js +++ b/bots/telegram/events/helper/aiResponse.js @@ -12,13 +12,14 @@ export default { if (response.threshold > intent.confidence) return; if (!response.reply) return; + // Because for some reason the markdown parser in TG is a pain in the ass, + // there won't be markdown support for now. bot.sendMessage( ids[0], `## ${response.reply.title}\n\n${response.reply.desc}\n\n_Confidence: ${intent.confidence}_\n\nThis bot is currently being tested in production. Ignore it, if it's wrong.`, { message_thread_id: ids[1], reply_to_message_id: ids[2], - parse_mode: 'Markdown' } );