c14635769d
This commit adds a new block of code to handle cases where the chatbot generates an empty response, which was previously causing a delay of one message in the conversation. The new code selects a random message from a predefined list of human-like responses to notify the user that an error has occurred, then resets the conversation history and deletes the memory map for that user. This ensures that subsequent messages from the same user will not be delayed due to the empty response.
175 lines
6.1 KiB
JavaScript
175 lines
6.1 KiB
JavaScript
const Discord = require('discord.js');
|
|
const fetch = require('node-fetch');
|
|
const emptyResponses = require('./assets/emptyMessages.js');
|
|
const {resetResponses, userResetMessages} = require('./assets/resetMessages.js');
|
|
const {errorMessages, busyResponses} = require('./assets/errorMessages.js');
|
|
|
|
require('dotenv').config()
|
|
// hi
|
|
const {
|
|
Client,
|
|
GatewayIntentBits,
|
|
ActivityType,
|
|
Partials
|
|
} = require('discord.js');
|
|
|
|
const client = new Client({
|
|
intents: [
|
|
GatewayIntentBits.DirectMessages,
|
|
GatewayIntentBits.Guilds,
|
|
GatewayIntentBits.GuildBans,
|
|
GatewayIntentBits.GuildMessages,
|
|
GatewayIntentBits.MessageContent,
|
|
],
|
|
partials: [Partials.Channel],
|
|
});
|
|
|
|
const channelID = '1094494101631680653'; // Replace with your channel ID
|
|
const channelID2 = '1094628334727614605'; // Replace with your channel ID
|
|
|
|
const conversations = new Map();
|
|
|
|
client.once('ready', () => {
|
|
console.log('Bot is ready.');
|
|
client.user.setPresence({
|
|
activities: [{
|
|
name: `AI`,
|
|
type: ActivityType.Playing
|
|
}],
|
|
status: 'dnd',
|
|
});
|
|
});
|
|
|
|
client.on('messageCreate', async (message) => {
|
|
// Only respond in the specified channels
|
|
if (message.channel.id !== channelID && message.channel.id !== channelID2) {
|
|
return;
|
|
}
|
|
if (message.author.bot) return; // Ignore messages from bots
|
|
|
|
if (conversations.get(message.author.id)?.busy) {
|
|
message.delete()
|
|
const busyResponse = busyResponses[Math.floor(Math.random() * busyResponses.length)];
|
|
await message.author.send(busyResponse); // give a notification of reset using a human like response.
|
|
return;
|
|
}
|
|
|
|
const userID = message.author.id;
|
|
let conversation = conversations.get(userID) || {
|
|
messages: [],
|
|
busy: false
|
|
};
|
|
|
|
|
|
if (conversation.messages.length === 0) {
|
|
conversation.messages.push({
|
|
role: 'user',
|
|
content: `Welcome to our conversation your name is "llama".`
|
|
});
|
|
conversation.messages.push({
|
|
role: 'user',
|
|
content: `My name is ${message.author.username}.`
|
|
});
|
|
conversation.messages.push({
|
|
role: 'assistant',
|
|
content: `Hello, ${message.author.username}, I am here to answer any question you have, how may I help you?`
|
|
});
|
|
conversation.messages.push({
|
|
role: 'user',
|
|
content: message.cleanContent
|
|
});
|
|
|
|
} else {
|
|
// Append user message to conversation history
|
|
conversation.messages.push({
|
|
role: 'user',
|
|
content: message.cleanContent
|
|
});
|
|
}
|
|
if (message.content === '!reset' || message.content === '!r') {
|
|
conversations.delete(userID); // Delete user's conversation map if they request reset
|
|
const userResetMessage = userResetMessages[Math.floor(Math.random() * userResetMessages.length)];
|
|
await message.channel.send(userResetMessage); // give a notification of reset using a human like response.
|
|
return;
|
|
}
|
|
|
|
// Append user message to conversation history
|
|
conversation.messages.push({
|
|
role: 'user',
|
|
content: message.cleanContent
|
|
});
|
|
|
|
try {
|
|
conversation.busy = true;
|
|
|
|
const response = await generateResponse(conversation);
|
|
|
|
// Append bot message to conversation history
|
|
conversation.messages.push({
|
|
role: 'assistant',
|
|
content: response
|
|
});
|
|
|
|
if (response && response.trim()) {
|
|
// Send response to user if it's not empty
|
|
await message.channel.send(response);
|
|
conversation.busy = false;
|
|
} else {
|
|
// Handle empty response here
|
|
const randomResponse = emptyResponses[Math.floor(Math.random() * emptyResponses.length)];
|
|
// We had an empty response, create a new memory map for sanity.
|
|
await message.channel.send(randomResponse); // give the user a human like reponse about the error
|
|
conversations.delete(userID); // Delete user's conversation map if they request reset
|
|
const resetMessage = resetResponses[Math.floor(Math.random() * resetResponses.length)];
|
|
await message.channel.send(resetMessage); // give a notification of reset using a human like response.
|
|
conversation.busy = false;
|
|
}
|
|
conversations.set(userID, conversation); // Update user's conversation map in memory
|
|
} catch (err) {
|
|
console.error(err);
|
|
const errorMessage = errorMessages[Math.floor(Math.random() * errorMessages.length)];
|
|
await message.channel.send(errorMessage); // give a notification of reset using a human like response. } finally {
|
|
conversation.busy = false;
|
|
}
|
|
});
|
|
|
|
async function generateResponse(conversation) {
|
|
const controller = new AbortController();
|
|
const timeout = setTimeout(() => {
|
|
controller.abort();
|
|
}, 900000);
|
|
|
|
const messagesCopy = [...conversation.messages]; // create a copy of the messages array
|
|
|
|
try {
|
|
const response = await fetch(`http://${process.env.ROOT_IP}:${process.env.ROOT_PORT}/v1/chat/completions`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'accept': 'application/json',
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
messages: messagesCopy // use the copy of the messages array
|
|
}),
|
|
signal: controller.signal
|
|
});
|
|
|
|
const responseData = await response.json();
|
|
console.log(JSON.stringify(responseData))
|
|
const choice = responseData.choices[0];
|
|
|
|
// Remove "user None:" and any text after it from the response
|
|
const responseText = choice.message.content.trim();
|
|
const startIndex = responseText.indexOf('user None:');
|
|
const sanitizedResponse = startIndex === -1 ? responseText : responseText.substring(0, startIndex);
|
|
|
|
return sanitizedResponse;
|
|
} catch (err) {
|
|
throw err;
|
|
} finally {
|
|
clearTimeout(timeout);
|
|
}
|
|
}
|
|
|
|
|
|
client.login(process.env.THE_TOKEN); // Replace with your bot token
|