'use strict'; const axios = require('axios'); const conf = require('../conf'); const {sleep} = require('../utils'); const { GoogleGenerativeAI, HarmCategory, HarmBlockThreshold, } = require("@google/generative-ai"); class Ai{ constructor(args){ this.bot = args.bot; this.promptName = args.promptName; this.prompCustom = args.prompCustom || ''; this.intervalLength = args.intervalLength || 30; this.intervalStop; this.messageListener; } async init(){ await this.start(); this.bot.on('onReady', async (argument)=>{ try{ await sleep(1000); let messages = ['']; this.messageListener = this.bot.on('message', (message, type)=>{ if(type === 'game_info') return; if(message.toString().startsWith('<') && message.toString().split('>')[0].includes(this.bot.bot.entity.username)){ console.log('message blocked from message array') return; } console.log(`Message ${type}: ${message.toString()}`) messages.push('>', message.toString()); }); this.intervalStop = setInterval(async ()=>{ let result; // if(messages.length ===0) return; try{ result = await this.chat(JSON.stringify({ messages, currentTime:Date.now()+1} )); }catch(error){ console.log('error AI API', error, result); messages = []; return ; } try{ messages = ['']; if(!result.response.text()) return; for(let message of JSON.parse(result.response.text())){ console.log('toSay', message.delay, message.text); if(message.text === '___') return; setTimeout(async (message)=>{ await this.bot.sayAiSafe(message.text); }, message.delay*1000, message); } }catch(error){ console.log('Error in AI message loop', error, result); if(result || result.response || result.response.text()){ console.log(result.response.text()) } } }, this.intervalLength*1000); }catch(error){ console.log('error in onReady', error); } }); } async unload(){ if(this.intervalStop){ clearInterval(this.intervalStop); this.intervalStop = undefined; } this.messageListener(); return true; } __settings(history){ return { generationConfig: { temperature: 1, topP: 0.95, topK: 64, maxOutputTokens: 8192, responseMimeType: "application/json", }, safetySettings:[ // See https://ai.google.dev/gemini-api/docs/safety-settings { category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_NONE, }, { category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_NONE, }, { category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: HarmBlockThreshold.BLOCK_NONE, }, { category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: HarmBlockThreshold.BLOCK_NONE, }, ], history: history || [ { role: "user", parts: [ {text: this.prompt}, ], }, { role: "model", parts: [ {text: "Chat stuff"}, ], } ], } } async start(history){ const genAI = new GoogleGenerativeAI(conf.ai.key); const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash", }); let bulbaItems = await axios.get('https://webstore.bulbastore.uk/api/listings'); bulbaItems = bulbaItems.data.listings.map(i=>i.listing_name); console.log('AI for prompts', conf.ai.prompts) this.prompt = conf.ai.prompts[this.promptName]( this.bot.bot.entity.username, conf.ai.interval, Object.values(this.bot.getPlayers()).map(player=>`<[${player.lvl}] ${player.username}>`).join('\n'), bulbaItems, this.prompCustom, ); this.session = model.startChat({ ...this.__settings(history), // systemInstruction: this.prompt, }); } async chat(message, retryCount=0){ console.log('chat', retryCount) try{ let result = await this.session.sendMessage(message); return result }catch(error){ console.log('AI chat error', error) if(retryCount > 3){ console.log('hit retry count'); return ; }; await sleep(500); this.session.params.history.pop(); this.start(this.session.params.history); return await this.chat(message, retryCount++) } } } module.exports = Ai; // run();