2024-10-11 09:46:18 -04:00

190 lines
4.2 KiB
JavaScript

'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();