feat: training and replies changed

This commit is contained in:
GramingFoxTeam
2023-03-20 21:28:52 +03:00
parent 1909e2c421
commit 715aa918cf
16 changed files with 187 additions and 106 deletions

View File

@@ -27,7 +27,10 @@
{ {
"label": "DOWNLOAD", "label": "DOWNLOAD",
"threshold": 0.85, "threshold": 0.85,
"text": "the download?" "reply": {
"title": "download??",
"desc": "the download?"
}
} }
] ]
} }

View File

@@ -5,6 +5,9 @@ export default {
once: false, once: false,
execute(helper, _, msg) { execute(helper, _, msg) {
if (!msg.content || msg.author.bot) return; if (!msg.content || msg.author.bot) return;
helper.scanText(msg.content.toLowerCase().replace(/<.*?>/g, ''), `${msg.channelId}/${msg.id}`); helper.scanText(
msg.content.toLowerCase().replace(/<.*?>/g, ''),
`${msg.channelId}/${msg.id}`
);
} }
}; };

View File

@@ -23,19 +23,26 @@ export default {
message = channel.messages.cache.get(ids[1]); message = channel.messages.cache.get(ids[1]);
} }
const intent = aiRes.response.reduce((a, b) => a.confidence > b.confidence ? a : b); const intent = aiRes.response.reduce((a, b) =>
const response = config.responses.find((res) => res.label === intent.name); a.confidence > b.confidence ? a : b
);
const response = config.responses.find(
(res) => res.label === intent.name
);
if (response.threshold > intent.confidence) return; if (response.threshold > intent.confidence) return;
if (!response.reply) return;
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
.setTitle('You have asked a Frequently Asked Question') .setTitle(response.reply.title)
.setDescription(response.text) .setDescription(response.reply.desc)
.setFooter({ text: `Confidence: ${intent.confidence}` }); .setColor(14908858)
.setFooter({ text: `Confidence: ${intent.confidence}` });
message.reply({ embeds: [embed]}); message.reply({ embeds: [embed] });
return; return;
} catch (e) {console.log(e)} } catch (e) {
console.log(e);
}
} }
}; };

View File

@@ -8,75 +8,78 @@ const __dirname = dirname(__filename);
import HelperClient from '../../client/index.js'; import HelperClient from '../../client/index.js';
export default async () => { export default async () => {
const config = JSON.parse(readFileSync('./config.json', 'utf-8')); const config = JSON.parse(readFileSync('./config.json', 'utf-8'));
const helper = new HelperClient(config); const helper = new HelperClient(config);
helper.connect(); helper.connect();
const client = new Client({ const client = new Client({
intents: [ intents: [
GatewayIntentBits.Guilds, GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent GatewayIntentBits.MessageContent
] ]
}); });
client.commands = new Collection(); client.commands = new Collection();
const commandsPath = join(__dirname, 'commands'); const commandsPath = join(__dirname, 'commands');
const commandFiles = readdirSync(commandsPath).filter((file) => const commandFiles = readdirSync(commandsPath).filter((file) =>
file.endsWith('.js') file.endsWith('.js')
); );
for (const file of commandFiles) { for (const file of commandFiles) {
const filePath = join(commandsPath, file); const filePath = join(commandsPath, file);
const command = (await import(`file://${filePath}`)).default; const command = (await import(`file://${filePath}`)).default;
if ('data' in command && 'execute' in command) { if ('data' in command && 'execute' in command) {
client.commands.set(command.data.name, command); client.commands.set(command.data.name, command);
} else { } else {
console.log( console.log(
`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.` `[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`
); );
}
} }
}
const discordEventsPath = join(__dirname, 'events/discord'); const discordEventsPath = join(__dirname, 'events/discord');
const discordEventFiles = readdirSync(discordEventsPath).filter((file) => const discordEventFiles = readdirSync(discordEventsPath).filter((file) =>
file.endsWith('.js') file.endsWith('.js')
); );
for (const file of discordEventFiles) { for (const file of discordEventFiles) {
const filePath = join(discordEventsPath, file); const filePath = join(discordEventsPath, file);
const event = (await import(`file://${filePath}`)).default; const event = (await import(`file://${filePath}`)).default;
if (event.once) { if (event.once) {
client.once(event.name, (...args) => client.once(event.name, (...args) =>
event.execute(helper, config, ...args) event.execute(helper, config, ...args)
); );
} else { } else {
client.on(event.name, (...args) => event.execute(helper, config, ...args)); client.on(event.name, (...args) =>
event.execute(helper, config, ...args)
);
}
} }
}
// The ReVanced Helper events. // The ReVanced Helper events.
const helperEventsPath = join(__dirname, 'events/helper'); const helperEventsPath = join(__dirname, 'events/helper');
const helperEventFiles = readdirSync(helperEventsPath).filter((file) => const helperEventFiles = readdirSync(helperEventsPath).filter((file) =>
file.endsWith('.js') file.endsWith('.js')
); );
for (const file of helperEventFiles) { for (const file of helperEventFiles) {
const filePath = join(helperEventsPath, file); const filePath = join(helperEventsPath, file);
const event = (await import(`file://${filePath}`)).default; const event = (await import(`file://${filePath}`)).default;
if (event.once) { if (event.once) {
helper.once(event.name, (...args) => helper.once(event.name, (...args) =>
event.execute(client, config, ...args) event.execute(client, config, ...args)
); );
} else { } else {
helper.on(event.name, (...args) => event.execute(client, config, ...args)); helper.on(event.name, (...args) =>
event.execute(client, config, ...args)
);
}
} }
}
client.login(config.discord.token); client.login(config.discord.token);
};
}

View File

@@ -1,13 +1,13 @@
import { readdirSync } from 'node:fs'; import { readdirSync } from 'node:fs';
const botFolders = readdirSync('./', { withFileTypes: true }) const botFolders = readdirSync('./', { withFileTypes: true })
.filter(dirent => dirent.isDirectory()) .filter((dirent) => dirent.isDirectory())
.map(dirent => dirent.name); .map((dirent) => dirent.name);
const runBotOnly = process.argv[2] ? process.argv[2] : null; const runBotOnly = process.argv[2] ? process.argv[2] : null;
for (const botFolder of botFolders) { for (const botFolder of botFolders) {
if (botFolder === 'node_modules') continue; if (botFolder === 'node_modules') continue;
if (runBotOnly && runBotOnly !== botFolder) continue; if (runBotOnly && runBotOnly !== botFolder) continue;
const botIndex = await import(`./${botFolder}/index.js`); const botIndex = await import(`./${botFolder}/index.js`);
botIndex.default(); botIndex.default();
} }

View File

@@ -6,23 +6,33 @@ export default {
if (!aiRes.response[0]) return; if (!aiRes.response[0]) return;
const ids = aiRes.id.split('/'); const ids = aiRes.id.split('/');
const intent = aiRes.response.reduce((a, b) => a.confidence > b.confidence ? a : b); const intent = aiRes.response.reduce((a, b) =>
a.confidence > b.confidence ? a : b
);
const response = config.responses.find((res) => res.label === intent.name); const response = config.responses.find((res) => res.label === intent.name);
if (response.threshold > intent.confidence) return; if (response.threshold > intent.confidence) return;
if (!response.reply) return;
switch (ids[0]) { switch (ids[0]) {
case 'comment': { case 'comment': {
client.getComment(ids[1]).reply(`${response.text}\n\n*Confidence: ${intent.confidence}*`); client
break; .getComment(ids[1])
} .reply(
`## ${response.reply.title}\n\n${response.reply.desc}\n\n*Confidence: ${intent.confidence}*\n\nThis bot is currently being tested in production. Ignore it, if it's wrong.`
);
break;
}
case 'post': { case 'post': {
client.getSubmission(ids[1]).reply(`${response.text}\n\n*Confidence: ${intent.confidence}*`); client
break; .getSubmission(ids[1])
} .reply(
`## ${response.reply.title}\n\n${response.reply.desc}\n\n*Confidence: ${intent.confidence}*\n\nThis bot is currently being tested in production. Ignore it, if it's wrong.`
);
break;
}
} }
return; return;
} }
}; };

View File

@@ -97,7 +97,9 @@ export default async () => {
event.execute(client, config, ...args) event.execute(client, config, ...args)
); );
} else { } else {
helper.on(event.name, (...args) => event.execute(client, config, ...args)); helper.on(event.name, (...args) =>
event.execute(client, config, ...args)
);
} }
} }
} };

View File

@@ -5,15 +5,22 @@ export default {
if (!aiRes.response) return; if (!aiRes.response) return;
if (!aiRes.response[0]) return; if (!aiRes.response[0]) return;
const ids = aiRes.id.split('/'); const ids = aiRes.id.split('/');
const intent = aiRes.response.reduce((a, b) => a.confidence > b.confidence ? a : b); const intent = aiRes.response.reduce((a, b) =>
a.confidence > b.confidence ? a : b
);
const response = config.responses.find((res) => res.label === intent.name); const response = config.responses.find((res) => res.label === intent.name);
if (response.threshold > intent.confidence) return; if (response.threshold > intent.confidence) return;
if (!response.reply) return;
bot.sendMessage(ids[0], `${response.text}\n\n*Confidence: ${intent.confidence}*`, { bot.sendMessage(
message_thread_id: ids[1], ids[0],
reply_to_message_id: ids[2], `## ${response.reply.title}\n\n${response.reply.desc}\n\n_Confidence: ${intent.confidence}_\n\nThis bot is currently being tested in production. Ignore it, if it's wrong.`,
parse_mode: 'HTML' {
}); message_thread_id: ids[1],
reply_to_message_id: ids[2],
parse_mode: 'Markdown'
}
);
return; return;
} }

View File

@@ -66,4 +66,4 @@ export default async () => {
helper.on(event.name, (...args) => event.execute(bot, config, ...args)); helper.on(event.name, (...args) => event.execute(bot, config, ...args));
} }
} }
} };

View File

@@ -13,7 +13,9 @@
}, },
"homepage": "https://github.com/reisxd/revanced-helper#readme", "homepage": "https://github.com/reisxd/revanced-helper#readme",
"scripts": { "scripts": {
"lint": "prettier --write . && eslint --fix ." "lint": "prettier --write . && eslint --fix .",
"installPackages": "cd bots && npm i && cd ../client && npm i && cd ../server && npm i",
"start": "cd bots && node . & cd ../server && node ."
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.27.0", "eslint": "^8.27.0",

View File

@@ -2,7 +2,7 @@
The server uses TCP for connection and BSON for messages, so you need to serialize and deserialize the messages. The server uses TCP for connection and BSON for messages, so you need to serialize and deserialize the messages.
# AI ## AI
Sending the server this JSON (BSON) will send you back the AI predictions. Sending the server this JSON (BSON) will send you back the AI predictions.
@@ -20,11 +20,28 @@ And the server would return something like this:
{ {
"op": 2, "op": 2,
"id": "String", "id": "String",
"response": "I think the term afn is just a generic slang term for the app that allows you to modify the behavior of Dalvik based android application..." "response": [
{
"confidence": 0.99,
"id": "String",
"name": "revanced_download"
}
]
```
### Training the AI
To train the AI, send the server a JSON (BSON) like this:
```json
{
"op": 3,
"label": "revanced_download",
"text": "how to download revanced"
} }
``` ```
# OCR ## OCR
Sending the server this JSON (BSON) will send you back the read text. Sending the server this JSON (BSON) will send you back the read text.

View File

@@ -1,11 +1,14 @@
import { serialize } from 'bson'; import { serialize } from 'bson';
export default async function runAI(client, data, config) { export default async function runAI(client, data, config) {
const witAIReq = await fetch(`https://api.wit.ai/message?v20230319&q=${encodeURI(data.text)}`, { const witAIReq = await fetch(
headers: { `https://api.wit.ai/message?v20230319&q=${encodeURI(data.text)}`,
authorization: `Bearer ${config.authToken}` {
headers: {
authorization: `Bearer ${config.authToken}`
}
} }
}); );
const response = await witAIReq.json(); const response = await witAIReq.json();

View File

@@ -1,4 +1,5 @@
import runAI from './ai.js'; import runAI from './ai.js';
import runOCR from './ocr.js'; import runOCR from './ocr.js';
import trainAI from './train.js';
export { runAI, runOCR }; export { runAI, runOCR, trainAI };

18
server/events/train.js Normal file
View File

@@ -0,0 +1,18 @@
export default async function runAI(data, config) {
fetch('https://api.wit.ai/utterances', {
headers: {
authorization: `Bearer ${config.authToken}`
},
body: JSON.stringify([
{
text: data.text,
intent: data.label,
entities: [],
traits: []
}
]),
method: 'POST'
});
return;
}

View File

@@ -3,7 +3,7 @@ const config = JSON.parse(readFileSync('./config.json', 'utf-8'));
import { createServer } from 'node:net'; import { createServer } from 'node:net';
import { deserialize } from 'bson'; import { deserialize } from 'bson';
import { runAI, runOCR } from './events/index.js'; import { runAI, runOCR, trainAI } from './events/index.js';
const server = createServer(async (client) => { const server = createServer(async (client) => {
client.on('data', async (data) => { client.on('data', async (data) => {
@@ -17,6 +17,11 @@ const server = createServer(async (client) => {
break; break;
} }
case 3: {
trainAI(eventData, config.witAI);
break;
}
case 5: { case 5: {
runOCR(client, eventData); runOCR(client, eventData);
break; break;