Add message seeding feature

This commit is contained in:
Charlie Laabs
2022-01-02 14:37:01 -06:00
parent a7699f1992
commit 914c355ad0
4 changed files with 40 additions and 22 deletions

14
package-lock.json generated
View File

@@ -23,7 +23,7 @@
"erlpack": "github:discord/erlpack", "erlpack": "github:discord/erlpack",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"json5": "^2.2.0", "json5": "^2.2.0",
"markov-strings-db": "^4.1.3", "markov-strings-db": "^4.1.4",
"pino": "^7.5.1", "pino": "^7.5.1",
"pino-pretty": "^7.3.0", "pino-pretty": "^7.3.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
@@ -2681,9 +2681,9 @@
"dev": true "dev": true
}, },
"node_modules/markov-strings-db": { "node_modules/markov-strings-db": {
"version": "4.1.3", "version": "4.1.4",
"resolved": "https://registry.npmjs.org/markov-strings-db/-/markov-strings-db-4.1.3.tgz", "resolved": "https://registry.npmjs.org/markov-strings-db/-/markov-strings-db-4.1.4.tgz",
"integrity": "sha512-F/ZPN6Azys7zi58KbAzwvns8p99o5v6BVpBORsKqTyWJJx76caNOLSh4fzm0RIPLEm4tXVw9HIXx1YX4AxYJyQ==", "integrity": "sha512-Uq7Z3n7EWO+htgDuWV6bueMd9TFINtNL4NRikll8DkypNrxqiB1zaPvOakOOAvoeCthq+A4JDHeyVqHKXolehg==",
"dependencies": { "dependencies": {
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"typeorm": "^0.2.41" "typeorm": "^0.2.41"
@@ -6431,9 +6431,9 @@
"dev": true "dev": true
}, },
"markov-strings-db": { "markov-strings-db": {
"version": "4.1.3", "version": "4.1.4",
"resolved": "https://registry.npmjs.org/markov-strings-db/-/markov-strings-db-4.1.3.tgz", "resolved": "https://registry.npmjs.org/markov-strings-db/-/markov-strings-db-4.1.4.tgz",
"integrity": "sha512-F/ZPN6Azys7zi58KbAzwvns8p99o5v6BVpBORsKqTyWJJx76caNOLSh4fzm0RIPLEm4tXVw9HIXx1YX4AxYJyQ==", "integrity": "sha512-Uq7Z3n7EWO+htgDuWV6bueMd9TFINtNL4NRikll8DkypNrxqiB1zaPvOakOOAvoeCthq+A4JDHeyVqHKXolehg==",
"requires": { "requires": {
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"typeorm": "^0.2.41" "typeorm": "^0.2.41"

View File

@@ -44,7 +44,7 @@
"erlpack": "github:discord/erlpack", "erlpack": "github:discord/erlpack",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"json5": "^2.2.0", "json5": "^2.2.0",
"markov-strings-db": "^4.1.3", "markov-strings-db": "^4.1.4",
"pino": "^7.5.1", "pino": "^7.5.1",
"pino-pretty": "^7.3.0", "pino-pretty": "^7.3.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",

View File

@@ -25,6 +25,14 @@ export const messageCommand = new SlashCommandBuilder()
.setName('debug') .setName('debug')
.setDescription('Follow up the generated message with the detailed sources that inspired it.') .setDescription('Follow up the generated message with the detailed sources that inspired it.')
.setRequired(false) .setRequired(false)
)
.addStringOption((seed) =>
seed
.setName('seed')
.setDescription(
`A ${config.stateSize}-word phrase to attempt to start a generated sentence with.`
)
.setRequired(false)
); );
/** /**

View File

@@ -344,6 +344,12 @@ interface GenerateResponse {
error?: Discord.MessageOptions; error?: Discord.MessageOptions;
} }
interface GenerateOptions {
tts?: boolean;
debug?: boolean;
startSeed?: string;
}
/** /**
* General Markov-chain response function * General Markov-chain response function
* @param interaction The message that invoked the action, used for channel info. * @param interaction The message that invoked the action, used for channel info.
@@ -353,10 +359,10 @@ interface GenerateResponse {
*/ */
async function generateResponse( async function generateResponse(
interaction: Discord.Message | Discord.CommandInteraction, interaction: Discord.Message | Discord.CommandInteraction,
debug = false, options?: GenerateOptions
tts = false
): Promise<GenerateResponse> { ): Promise<GenerateResponse> {
L.debug('Responding...'); L.debug({ options }, 'Responding...');
const { tts = false, debug = false, startSeed } = options || {};
if (!interaction.guildId) { if (!interaction.guildId) {
L.warn('Received an interaction without a guildId'); L.warn('Received an interaction without a guildId');
return { message: { content: INVALID_GUILD_MESSAGE } }; return { message: { content: INVALID_GUILD_MESSAGE } };
@@ -368,6 +374,7 @@ async function generateResponse(
const markov = await getMarkovByGuildId(interaction.guildId); const markov = await getMarkovByGuildId(interaction.guildId);
try { try {
markovGenerateOptions.startSeed = startSeed;
const response = await markov.generate<MarkovDataCustom>(markovGenerateOptions); const response = await markov.generate<MarkovDataCustom>(markovGenerateOptions);
L.info({ string: response.string }, 'Generated response text'); L.info({ string: response.string }, 'Generated response text');
L.debug({ response }, 'Generated response object'); L.debug({ response }, 'Generated response object');
@@ -539,33 +546,35 @@ client.on('messageCreate', async (message) => {
} }
if (command === 'tts') { if (command === 'tts') {
L.debug('Responding to legacy command tts'); L.debug('Responding to legacy command tts');
const generatedResponse = await generateResponse(message, false, true); const generatedResponse = await generateResponse(message, { tts: true });
if (generatedResponse.message) await message.reply(generatedResponse.message); if (generatedResponse.message) await message.reply(generatedResponse.message);
if (generatedResponse.debug) await message.reply(generatedResponse.debug); if (generatedResponse.debug) await message.reply(generatedResponse.debug);
if (generatedResponse.error) await message.reply(generatedResponse.error); if (generatedResponse.error) await message.reply(generatedResponse.error);
} }
if (command === 'debug') { if (command === 'debug') {
L.debug('Responding to legacy command debug'); L.debug('Responding to legacy command debug');
const generatedResponse = await generateResponse(message, true); const generatedResponse = await generateResponse(message, { debug: true });
if (generatedResponse.message) await message.reply(generatedResponse.message); if (generatedResponse.message) await message.reply(generatedResponse.message);
if (generatedResponse.debug) await message.reply(generatedResponse.debug); if (generatedResponse.debug) await message.reply(generatedResponse.debug);
if (generatedResponse.error) await message.reply(generatedResponse.error); if (generatedResponse.error) await message.reply(generatedResponse.error);
} }
if (command === null) { if (command === null) {
if (!message.author.bot) { if (!message.author.bot) {
if (client.user && message.mentions.has(client.user)) {
L.debug('Responding to mention');
// <@!278354154563567636> how are you doing?
const startSeed = message.content.replace(/<@!\d+>/g, '').trim();
const generatedResponse = await generateResponse(message, { startSeed });
if (generatedResponse.message) await message.reply(generatedResponse.message);
if (generatedResponse.debug) await message.reply(generatedResponse.debug);
if (generatedResponse.error) await message.reply(generatedResponse.error);
}
if (await isValidChannel(message.channelId)) { if (await isValidChannel(message.channelId)) {
L.debug('Listening'); L.debug('Listening');
const markov = await getMarkovByGuildId(message.channel.guildId); const markov = await getMarkovByGuildId(message.channel.guildId);
await markov.addData([messageToData(message)]); await markov.addData([messageToData(message)]);
} }
if (client.user && message.mentions.has(client.user)) {
L.debug('Responding to mention');
const generatedResponse = await generateResponse(message);
if (generatedResponse.message) await message.reply(generatedResponse.message);
if (generatedResponse.debug) await message.reply(generatedResponse.debug);
if (generatedResponse.error) await message.reply(generatedResponse.error);
}
} }
} }
}); });
@@ -603,7 +612,8 @@ client.on('interactionCreate', async (interaction) => {
await interaction.deferReply(); await interaction.deferReply();
const tts = interaction.options.getBoolean('tts') || false; const tts = interaction.options.getBoolean('tts') || false;
const debug = interaction.options.getBoolean('debug') || false; const debug = interaction.options.getBoolean('debug') || false;
const generatedResponse = await generateResponse(interaction, debug, tts); const startSeed = interaction.options.getString('seed')?.trim() || undefined;
const generatedResponse = await generateResponse(interaction, { tts, debug, startSeed });
if (generatedResponse.message) await interaction.editReply(generatedResponse.message); if (generatedResponse.message) await interaction.editReply(generatedResponse.message);
else await interaction.deleteReply(); else await interaction.deleteReply();
if (generatedResponse.debug) await interaction.followUp(generatedResponse.debug); if (generatedResponse.debug) await interaction.followUp(generatedResponse.debug);