current status
This commit is contained in:
parent
1b80d11a2c
commit
2ac0d2de6f
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
node_modules/
|
||||||
|
conversations/
|
||||||
|
config.json
|
10
config.example.json
Normal file
10
config.example.json
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"api": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 5001,
|
||||||
|
"bearer": ""
|
||||||
|
},
|
||||||
|
"initiative": [],
|
||||||
|
"stops": ["###"],
|
||||||
|
"clients": []
|
||||||
|
}
|
34
src/inc/lib.mjs
Normal file
34
src/inc/lib.mjs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import { exec as _exec } from 'node:child_process';
|
||||||
|
import fetch from 'node-fetch';
|
||||||
|
|
||||||
|
export default new class {
|
||||||
|
exec(cmd) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
_exec(cmd, { maxBuffer: 5e3 * 1024 }, (err, stdout, stderr) => {
|
||||||
|
if(err)
|
||||||
|
return reject(err);
|
||||||
|
if(stderr)
|
||||||
|
console.error(stderr);
|
||||||
|
resolve({ stdout: stdout });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
rand(max = 1) {
|
||||||
|
return ~~(Math.random() * (max - 1) + 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
async getPlayerlist(world, clanid) {
|
||||||
|
const res = await (await fetch(`https://${world}.freewar.de/freewar/dump_players.php`)).text();
|
||||||
|
return res.split("\n").map(p => {
|
||||||
|
const player = p.split("\t");
|
||||||
|
return {
|
||||||
|
id: +player[0],
|
||||||
|
name: player[1],
|
||||||
|
xp: +player[2],
|
||||||
|
rasse: player[3],
|
||||||
|
clanid: +player[4]
|
||||||
|
};
|
||||||
|
}).filter(p => p.clanid === clanid)
|
||||||
|
};
|
||||||
|
};
|
169
src/index.mjs
169
src/index.mjs
|
@ -2,60 +2,147 @@ import fs from 'node:fs/promises';
|
||||||
import cuffeo from 'cuffeo';
|
import cuffeo from 'cuffeo';
|
||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
import oger from './inc/oger.mjs';
|
import oger from './inc/oger.mjs';
|
||||||
|
import lib from './inc/lib.mjs';
|
||||||
import config from '../config.json' assert { type: 'json' };
|
import config from '../config.json' assert { type: 'json' };
|
||||||
import initials from './inc/initials.json' assert { type: 'json' };
|
import initials from '../data/initials.json' assert { type: 'json' };
|
||||||
|
|
||||||
const conversations = new Map();
|
const conversations = new Map();
|
||||||
const bot = await new cuffeo(config.clients);
|
const bot = await new cuffeo(config.clients);
|
||||||
let last = false;
|
let last = false;
|
||||||
|
let playerlist = false;
|
||||||
|
|
||||||
bot.on('message', async e => {
|
bot.on('message', async e => {
|
||||||
|
if(typeof e.message === 'undefined' || e.message.length <= 2)
|
||||||
|
return;
|
||||||
|
|
||||||
console.log(e.user.nick + ": " + e.message);
|
console.log(e.user.nick + ": " + e.message);
|
||||||
const constr = `${e.network}::${e.channelid}`;
|
const constr = `${e.network}::${e.channelid}`;
|
||||||
|
|
||||||
if(e.message?.match(/^!perf/i)) {
|
if(e.message.match(/^!claninfo/i)) {
|
||||||
return await e.reply(JSON.stringify(await (await fetch(`http://${config.api.host}:${config.api.port}/api/extra/perf`)).json()));
|
playerlist = await lib.getPlayerlist("welt13", 4760);
|
||||||
|
|
||||||
|
return await e.reply(
|
||||||
|
playerlist.map(p => p.name).join(", ")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(e.message?.match(/^!model/i)) {
|
if(e.message.match(/^!gens/i)) {
|
||||||
|
const perf = await (await fetch(`http://${config.api.host}:${config.api.port}/api/extra/perf`)).json();
|
||||||
|
return await e.reply(`total_gens: ${perf.total_gens}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e.message.match(/^!model/i)) {
|
||||||
return await e.reply((await (await fetch(`http://${config.api.host}:${config.api.port}/api/v1/model`)).json()).result);
|
return await e.reply((await (await fetch(`http://${config.api.host}:${config.api.port}/api/v1/model`)).json()).result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(e.message?.match(/^!channelid/i)) {
|
if(e.message.match(/^!messages/i)) {
|
||||||
|
try {
|
||||||
|
const cons = (await fs.readdir("./data/conversations")).filter(f => f.endsWith(".json"));
|
||||||
|
let messages = 0;
|
||||||
|
for(const con of cons) {
|
||||||
|
messages += JSON.parse(await fs.readFile(`./data/conversations/${con}`, 'utf8')).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
let output = [];
|
||||||
|
output.push(`Nachrichten insgesamt: ${messages}`);
|
||||||
|
|
||||||
|
if(cons.includes(constr+'.json')) {
|
||||||
|
output.push(`Davon in diesem Kanal: ${JSON.parse(await fs.readFile(`./data/conversations/${constr}.json`, 'utf8')).length}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await e.reply(output.join(' | '));
|
||||||
|
} catch(err) {
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e.message.match(/^!gpustat/i)) {
|
||||||
|
const gpustat = JSON.parse((await lib.exec('gpustat -a --json')).stdout);
|
||||||
|
const gpu = gpustat.gpus[0];
|
||||||
|
|
||||||
|
const output = [
|
||||||
|
`${gpu['temperature.gpu']}°C, ${gpu['fan.speed']} rpm`,
|
||||||
|
`${gpu['memory.used']} / ${gpu['memory.total']} MB`,
|
||||||
|
`${gpu['power.draw']} / ${gpu['enforced.power.limit']} W`
|
||||||
|
].join(' | ');
|
||||||
|
return await e.reply(`${gpustat.hostname}: ${gpu.name}\n${output}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e.message.match(/^!channelid/i)) {
|
||||||
return await e.reply(e.channelid);
|
return await e.reply(e.channelid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!conversations.has(constr)) { // get conv from json
|
if(e.message.match(/^!reset/i)) {
|
||||||
try {
|
conversations.set(constr, []);
|
||||||
const tmpcon = JSON.parse(await fs.readFile(`./src/conversations/${constr}.json`, 'utf8'));
|
await fs.writeFile(`./data/conversations/${constr}.json`, JSON.stringify([]));
|
||||||
|
return await e.reply("Konversation wurde erfolgreich zurückgesetzt.");
|
||||||
|
}
|
||||||
|
|
||||||
|
let conv = conversations.has(constr) ? conversations.get(constr) : [];
|
||||||
|
|
||||||
|
if(!conv.length) {
|
||||||
|
try { // get conv from json
|
||||||
|
const tmpcon = JSON.parse(await fs.readFile(`./data/conversations/${constr}.json`, 'utf8'));
|
||||||
if(tmpcon) {
|
if(tmpcon) {
|
||||||
conversations.set(constr, tmpcon);
|
conv = tmpcon;
|
||||||
console.log(`Konversation von ${constr} geladen. ${tmpcon.length} Einträge.`);
|
console.log(`Konversation von ${constr} geladen. ${tmpcon.length} Einträge.`);
|
||||||
}
|
}
|
||||||
} catch(err) {}
|
} catch(err) {
|
||||||
|
console.error(err);
|
||||||
|
conversations.set(constr, conv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(e.message?.match(/ra+i+ne+r/i)) {
|
conv.push({
|
||||||
|
role: 'user',
|
||||||
|
content: `${e.user.nick} schreibt: ${e.message.trim()}`
|
||||||
|
});
|
||||||
|
await fs.writeFile(`./data/conversations/${constr}.json`, JSON.stringify(conv));
|
||||||
|
conversations.set(constr, conv);
|
||||||
|
|
||||||
|
if(!e.message?.match(/ra+i+ne+r/i)) {
|
||||||
|
if(!config.initiative.includes(constr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
let probability = 20; // default, 5%
|
||||||
|
|
||||||
|
if(e.message.match(/.*\?$/)) {
|
||||||
|
probability = 5; // 20%
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lib.rand(probability) !== 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Rainer matched
|
||||||
if(last)
|
if(last)
|
||||||
return await e.reply(`ich antworte bereits ${last}!`);
|
return await e.reply(`ich antworte bereits ${last}!`);
|
||||||
|
|
||||||
const actcon = [];
|
const actcon = [{
|
||||||
|
|
||||||
if(conversations.has(constr))
|
|
||||||
actcon.push(...conversations.get(constr));
|
|
||||||
else {
|
|
||||||
actcon.push({
|
|
||||||
"role": "system",
|
"role": "system",
|
||||||
"content": initials[e.channelid] ? initials[e.channelid].lore : initials['default'].lore
|
"content": initials[ initials[constr] ? constr : 'default' ].lore
|
||||||
});
|
}, {
|
||||||
actcon.push({
|
|
||||||
"role": "system",
|
"role": "system",
|
||||||
"content": "eingehende Chatnachrichten sind immer folgendermaßen aufgebaut: \"%USERNAME% schreibt: %COMMAND%\". Du schreibst das aber nicht."
|
"content": "eingehende Chatnachrichten sind immer folgendermaßen aufgebaut: \"%USERNAME% schreibt: %COMMAND%\". Du schreibst das aber nicht."
|
||||||
|
}, {
|
||||||
|
"role": "system",
|
||||||
|
"content": `Aktuelles Datum und Zeit: ${(new Date()).toLocaleString()}`
|
||||||
|
}];
|
||||||
|
|
||||||
|
if(constr === 'Discord::1143415824539992206') {
|
||||||
|
if(!playerlist)
|
||||||
|
playerlist = await lib.getPlayerlist('welt13', 4760);
|
||||||
|
|
||||||
|
actcon.push({
|
||||||
|
"role": "user",
|
||||||
|
"content": "Unser Clan besteht aus folgenden Mitgliedern:\n" + playerlist.map(p => `${p.name}: ${p.xp} XP, Rasse: ${p.rasse}`).join("\n")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
actcon.push({
|
actcon.push(...conv, {
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content: `${e.user.nick} schreibt: ${e.message.trim()}`
|
content: `${e.user.nick} schreibt: ${e.message.trim()}`
|
||||||
});
|
});
|
||||||
|
@ -71,31 +158,49 @@ bot.on('message', async e => {
|
||||||
mode: "chat",
|
mode: "chat",
|
||||||
instruction_template: "Alpaca",
|
instruction_template: "Alpaca",
|
||||||
stream: false,
|
stream: false,
|
||||||
max_tokens: 1024,
|
max_tokens: 768,
|
||||||
stop: ['###', ' <|endoftext|>', '---'],
|
stop: config.stops,
|
||||||
messages: actcon
|
messages: actcon
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
last = e.user.nick;
|
last = e.user.nick;
|
||||||
|
|
||||||
const res = await (await fetch(`http://${config.api.host}:${config.api.port}/v1/chat/completions`, opts)).json();
|
let res;
|
||||||
|
|
||||||
if(res.choices[0]?.message) {
|
try {
|
||||||
|
res = await (await fetch(`http://${config.api.host}:${config.api.port}/v1/chat/completions`, opts)).json();
|
||||||
|
} catch(err) {
|
||||||
|
last = false;
|
||||||
|
return await e.reply('Backend ist gerade offline. Sorreh.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(res?.choices?.[0]?.message) {
|
||||||
if(res.choices[0].message.length <= 2)
|
if(res.choices[0].message.length <= 2)
|
||||||
return await e.reply('ich habe dazu nichts zu sagen, du Birne.');
|
return await e.reply('ich habe dazu nichts zu sagen, du Birne.');
|
||||||
|
|
||||||
res.choices[0].message.content = res.choices[0].message.content.split(/(###|---)/)[0];
|
res.choices[0].message.content = res.choices[0].message.content.split(/(###|---|ASSISTANT)/)[0];
|
||||||
|
res.choices[0].message.content = res.choices[0].message.content.replace(/^Rainer( schreibt| antwortet)?: /, '');
|
||||||
|
|
||||||
actcon.push(res.choices[0].message);
|
conv.push(res.choices[0].message);
|
||||||
conversations.set(constr, actcon);
|
conversations.set(constr, conv);
|
||||||
|
await fs.writeFile(`./data/conversations/${constr}.json`, JSON.stringify(conv));
|
||||||
|
|
||||||
console.log("Rainer: " + res.choices[0].message.content.trim());
|
console.log("Rainer: " + res.choices[0].message.content.trim());
|
||||||
last = false;
|
|
||||||
|
|
||||||
await fs.writeFile(`./src/conversations/${constr}.json`, JSON.stringify(conversations.get(constr)));
|
try {
|
||||||
return await e.reply(res.choices[0].message.content.trim());
|
if(initials[constr] && initials[constr].langmod === 'oger')
|
||||||
|
await e.reply(oger(res.choices[0].message.content.trim()));
|
||||||
|
else
|
||||||
|
await e.reply(res.choices[0].message.content.trim());
|
||||||
|
} catch(err) {
|
||||||
|
await e.reply('ups, kann ich nicht schreiben, wäre zu viel gewesen.');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await e.reply('Hilfe, Fehler!');
|
||||||
|
}
|
||||||
|
|
||||||
last = false;
|
last = false;
|
||||||
}
|
return;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user