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("",historyNoEOL).replace("",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;