186 lines
5.0 KiB
JavaScript
186 lines
5.0 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": 240,
|
|
"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();
|
|
}
|
|
|
|
// appends b to a, but skips lines that are common to both b and a
|
|
async smart_append(a, b) {
|
|
let alines = a.split("\n");
|
|
let blines = b.split("\n");
|
|
for (let i = blines.length-1; i >= 0; i--) {
|
|
if (blines[i] == alines[alines.length-1]) {
|
|
alines.pop();
|
|
}
|
|
}
|
|
let newLines = alines.concat(blines).join('\n');
|
|
return newLines;
|
|
}
|
|
|
|
async logChat(chan, history) {
|
|
const chanName = chan.name;
|
|
const fileName = `bot-modules/botchat/logs/${chanName}.txt`;
|
|
if (fs.existsSync(fileName)) {
|
|
let log = fs.readFileSync(fileName, 'utf8');
|
|
//log += history;
|
|
log = await this.smart_append(log, history);
|
|
fs.writeFileSync(fileName, log);
|
|
} else {
|
|
fs.writeFileSync(fileName, history);
|
|
}
|
|
}
|
|
|
|
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`;
|
|
}
|
|
// Add to log
|
|
const fixedString = await this.inputFixup(chan, history);
|
|
try {
|
|
await this.logChat(chan, fixedString);
|
|
} catch (e) {
|
|
console.log(e.message);
|
|
}
|
|
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;
|