dank-bot-js/bot-modules/botchat/module.js

154 lines
4.2 KiB
JavaScript

const Discord = require("discord.js");
const fetch = require("node-fetch");
const fs = require('fs');
const server = "192.168.1.204";
class BotChat {
async get_response(history, input_text) {
let historyNoEOL = history;
if(history.endsWith("\n")) { //get rid of extra newline if it's there
historyNoEOL = history.slice(0,-1);
}
const complete_prompt = this.bot_prompt.replace("<CONVHISTORY>",historyNoEOL).replace("<INTEXT>",input_text);
console.log("PROMPT:" + complete_prompt);
const response = await fetch(`http://${server}:7860/run/textgen`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"data": [ JSON.stringify(
[
complete_prompt,
{
"max_new_tokens": 100,
"do_sample": true,
"temperature": 0.44,
"top_p": 1,
"typical_p": 1,
'repetition_penalty': 1.3,
'encoder_repetition_penalty': 1.0,
'top_k': 0,
'min_length': 0,
'no_repeat_ngram_size': 16,
'num_beams': 1,
'penalty_alpha': 0,
'length_penalty': 1,
'early_stopping': false,
'seed': -1
}
]) ]
}
)
});
const response_json = await response.json();
const full_text = response_json.data[0];
const completion = full_text.slice(complete_prompt.length);
console.log(`RESPONSE: ${completion}`);
//return response_json.text;
return completion;
}
constructor() {
this.matches = [ "botchat", "botmention", "botrandom" ];
this.bot_prompt = fs.readFileSync("bot-modules/botchat/prompts/default.txt").toString();
}
async getRecentChannelHistory(chan) {
let history = "";
// Fetch the last 10 messages in the channel
const messages = await chan.messages.fetch({ limit: 14 });
// Reverse the order of the messages so that the oldest one is first
const reversed = messages.reverse();
// Loop through the messages and print their content and author
for (let msg of reversed) {
const user = msg[1].author.username;
const content = msg[1].content;
history += `${user}: ${content}\n`;
}
const fixedString = this.inputFixup(chan, history);
return fixedString;
}
// Replace all the user IDs with their actual usernames
async inputFixup(chan,str) {
const client = chan.client;
const userStrs = str.match(/<@[0-9]+?>/g);
const uniqueIDs = [...new Set(userStrs)];
const translationTable = {};
for (let id of uniqueIDs) {
// Get the user object from the ID
const flake = id.slice(2,-1);
const user = await client.users.fetch(`${flake}`);
// Check if the user exists
if (user) {
translationTable[id] = user.username;
}
}
console.log(JSON.stringify(translationTable));
let new_input = str.replace("!botchat","bot,");
for (let t in translationTable) {
new_input = new_input.replaceAll(t, translationTable[t]);
}
return new_input;
}
async outputFixup(str) {
const outLines = str.trim().split("\n");
let outArr =[];
let outStr = "";
for (let ln of outLines) {
if(ln.startsWith("dank-bot:")) {
const trucStr = ln.replace("dank-bot:","");
outStr += "\n" + trucStr.trim();
outArr.push(trucStr.trim());
} else if (ln.indexOf(":") > 0 && ln.indexOf(":") < 20 ) {
break;
} else {
outStr += "\n" + ln.trim();
outArr.push(ln.trim());
}
}
outArr = outArr.filter(s => s.trim().length > 0);
// return outStr.trim();
return outArr;
}
async action(msg, botrandom) {
let chan = msg.channel;
try {
//const input_text = msg.content.replace("!botchat","").replace(/<@.+?>/,"bot,").trim();
const input_text = await this.inputFixup(chan, msg.content.trim());
await chan.sendTyping();
console.log(`Input Text: ${input_text}`);
const history = await this.getRecentChannelHistory(chan);
const bot_response = await this.get_response(history,input_text);
const responses_only = await this.outputFixup(bot_response);
if (responses_only.length > 1) {
responses_only.pop();
}
for(let res of responses_only) {
await chan.send(res);
}
// chan.send(response_only);
} catch (e) {
chan.send(`Error: ${e}`);
}
}
}
module.exports = BotChat;