Misc updates.

This commit is contained in:
jrmyr 2025-05-06 11:00:56 +00:00
parent 455233b1c4
commit 589360b412
6 changed files with 182 additions and 47 deletions

View File

@ -74,17 +74,15 @@ function splitMessage(text, maxLength = MAX_DISCORD_MSG_LENGTH) {
/**
* Determine whether the bot should respond to a message.
* Triggers when the bot is mentioned or when the message is a direct reply.
* @param {Message} message - The incoming Discord message.
* @param {string} botId - The bot user ID.
* @param {object} logger - Logger for debugging.
* @returns {Promise<boolean>} True if the bot should respond.
* Controlled by enableMentions and enableReplies in config.
*/
async function shouldRespond(message, botId, logger) {
async function shouldRespond(message, botId, cfg, logger) {
if (message.author.bot || !botId) return false;
const isMention = message.mentions.users.has(botId);
const enableMentions = cfg.enableMentions ?? true;
const enableReplies = cfg.enableReplies ?? true;
const isMention = enableMentions && message.mentions.users.has(botId);
let isReply = false;
if (message.reference?.messageId) {
if (enableReplies && message.reference?.messageId) {
try {
const ref = await message.channel.messages.fetch(message.reference.messageId);
isReply = ref.author.id === botId;
@ -248,7 +246,8 @@ async function onMessage(client, cfg, message) {
const logger = client.logger;
const botId = client.user?.id;
client.logger.debug(`[onMessage] Received message ${message.id} from ${message.author.id}`);
if (!(await shouldRespond(message, botId, logger))) return;
// Check if bot should respond, based on config (mentions/replies)
if (!(await shouldRespond(message, botId, cfg, logger))) return;
await message.channel.sendTyping();
// Determine channel/thread key for context

View File

@ -0,0 +1,37 @@
/**
* responsesRandomizer module
* Listens to all guild messages and randomly sends a generated narrative.
* Uses sendNarrative from responses.js.
*/
import { sendNarrative } from './responses.js';
/**
* Initialize the responsesRandomizer module.
* @param {import('discord.js').Client} client - Discord client instance.
* @param {object} clientConfig - Full client configuration object.
*/
export async function init(client, clientConfig) {
const cfg = clientConfig.responsesRandomizer;
const chance = Number(cfg.chance);
if (isNaN(chance) || chance <= 0) {
client.logger.warn(`[module:responsesRandomizer] Invalid chance value: ${cfg.chance}. Module disabled.`);
return;
}
client.logger.info(`[module:responsesRandomizer] Enabled with chance=${chance}`);
client.on('messageCreate', async (message) => {
try {
// Skip bot messages or non-guild messages
if (message.author.bot || !message.guild) return;
const content = message.content?.trim();
if (!content) return;
// Roll the dice
if (Math.random() > chance) return;
// Generate and send narrative
await sendNarrative(client, clientConfig.responses, message.channel.id, content);
} catch (err) {
client.logger.error(`[module:responsesRandomizer] Error processing message: ${err.message}`);
}
});
}

View File

@ -356,6 +356,8 @@ export const commands = [
}
await interaction.reply({ content: `Preset **${name}** saved.`, flags: MessageFlags.Ephemeral });
} else if (sub === 'reset') {
// Defer to avoid Discord interaction timeout during reset
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
// reset channel to default parameters
const owner = interaction.member;
const display = owner.displayName || owner.user.username;
@ -378,7 +380,7 @@ export const commands = [
]);
sess.roleId = guild.roles.everyone.id;
await client.pb.updateOne('tempvc_sessions', sess.pbId, { roleId: guild.roles.everyone.id, invitedUserIds: [] });
await interaction.reply({ content: 'Channel has been reset to default settings.', flags: MessageFlags.Ephemeral });
await interaction.editReply({ content: 'Channel has been reset to default settings.' });
} else if (sub === 'mode') {
const mode = interaction.options.getString('mode', true);
sess.mode = mode;
@ -396,13 +398,15 @@ export const commands = [
await client.pb.updateOne('tempvc_sessions', sess.pbId, { mode });
await interaction.reply({ content: `Channel mode set to **${mode}**.`, flags: MessageFlags.Ephemeral });
} else if (sub === 'restore') {
// Defer initial reply to extend Discord interaction window
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
const name = interaction.options.getString('name', true);
const preset = await client.pb.getFirst(
'tempvc_presets',
`guildId = "${guild.id}" && userId = "${interaction.user.id}" && name = "${name}"`
);
if (!preset) {
return interaction.reply({ content: `Preset **${name}** not found.`, flags: MessageFlags.Ephemeral });
return interaction.editReply({ content: `Preset **${name}** not found.` });
}
// apply settings
await voice.setName(preset.channelName);
@ -433,7 +437,7 @@ export const commands = [
{ roleId: preset.roleId || '', mode }
);
sess.roleId = preset.roleId || '';
await interaction.reply({ content: `Preset **${name}** restored (mode: ${mode}).`, flags: MessageFlags.Ephemeral });
await interaction.editReply({ content: `Preset **${name}** restored (mode: ${mode}).` });
}
} catch (err) {
client.logger.error(`[module:tempvc][vc] ${err.message}`);

View File

@ -53,6 +53,8 @@ export default {
defaultTemperature: 0.7,
conversationExpiry: 30 * 60 * 1000,
minScore: 1.0,
enableMentions: true,
enableReplies: true,
tools: {
webSearch: true,
fileSearch: false,
@ -174,6 +176,8 @@ export default {
defaultTemperature: 0.7,
conversationExpiry: 30 * 60 * 1000,
minScore: 0.5,
enableMentions: true,
enableReplies: true,
tools: {
webSearch: false,
fileSearch: false,
@ -260,6 +264,8 @@ export default {
defaultTemperature: 0.7,
conversationExpiry: 30 * 60 * 1000,
minScore: 0,
enableMentions: true,
enableReplies: true,
tools: {
webSearch: false,
fileSearch: false,
@ -282,6 +288,82 @@ export default {
},
{
id: 'GRANDPA',
enabled: true,
owner: process.env.OWNER_ID,
discord: {
appId: process.env.GRANDPA_DISCORD_APPID,
token: process.env.GRANDPA_DISCORD_TOKEN
},
logging: {
console: {
enabled: true,
colorize: true,
level: 'silly',
},
file: {
dateFormat: 'YYYY-MM-DD',
timestampFormat: 'YYYY-MM-DD HH:mm:ss',
combined: {
enabled: true,
level: 'silly',
location: 'logs',
maxSize: '12m',
maxFiles: '30d',
},
error: {
enabled: true,
level: 'error',
location: 'logs',
maxSize: '12m',
maxFiles: '365d',
}
}
},
pocketbase: {
url: process.env.SHARED_POCKETBASE_URL,
username: process.env.SHARED_POCKETBASE_USERNAME,
password: process.env.SHARED_POCKETBASE_PASSWORD
},
responses: {
apiKey: process.env.SHARED_OPENAI_API_KEY,
defaultModel: 'gpt-4.1',
defaultMaxTokens: 200,
defaultTemperature: 0.7,
conversationExpiry: 30 * 60 * 1000,
minScore: 0,
enableMentions: false,
enableReplies: true,
tools: {
webSearch: false,
fileSearch: false,
imageGeneration: false,
},
imageGeneration: {
defaultModel: 'gpt-image-1',
defaultQuality: 'standard',
imageSavePath: './images'
}
},
responsesRandomizer: {
chance: 0.01,
},
modules: [
'botUtils',
'pbUtils',
'responses',
'responsesPrompt',
'responsesRandomizer'
]
},
{
id: 'Smuuush',
enabled: true,
@ -331,6 +413,8 @@ export default {
defaultTemperature: 0.7,
conversationExpiry: 30 * 60 * 1000,
minScore: 0,
enableMentions: true,
enableReplies: true,
tools: {
webSearch: false,
fileSearch: false,

View File

@ -97,6 +97,8 @@ export default {
systemPromptPath: './prompts/IO3.txt',
conversationExpiry: 30 * 60 * 1000,
minScore: 1.0,
enableMentions: true,
enableReplies: true,
tools: {
webSearch: false,
fileSearch: false,
@ -114,18 +116,27 @@ export default {
baseOutput: 1000,
commendationValue: 1.0,
citationValue: 1.2,
cooldown: 0,
decay: 90,
schedule: '0 0 * * 0',
},
// Modules to load for this client
modules: [
'ansi',
'botUtils',
'pbUtils',
'gitUtils',
'condimentX',
'responses',
'responsesPrompt',
'responsesQuery',
'responsesRandomizer',
'messageQueue-example',
'scorekeeper',
'scorekeeper-example',
'condimentX',
'scExecHangarStatus',
'tempvc',
],
},
],

68
package-lock.json generated
View File

@ -42,9 +42,9 @@
}
},
"node_modules/@discordjs/builders": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.11.1.tgz",
"integrity": "sha512-2zDAVuoeAkdv0YQzYKO8vZfaDfB+1KZ60ymBKtD7QDpsh6lzAnQSUBLqeRkhlons6BT9+yRctOh9fPy94w6kDA==",
"version": "1.11.2",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.11.2.tgz",
"integrity": "sha512-F1WTABdd8/R9D1icJzajC4IuLyyS8f3rTOz66JsSI3pKvpCAtsMBweu8cyNYsIyvcrKAVn9EPK+Psoymq+XC0A==",
"license": "Apache-2.0",
"dependencies": {
"@discordjs/formatters": "^0.6.1",
@ -63,9 +63,9 @@
}
},
"node_modules/@discordjs/builders/node_modules/discord-api-types": {
"version": "0.38.1",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.1.tgz",
"integrity": "sha512-vsjsqjAuxsPhiwbPjTBeGQaDPlizFmSkU0mTzFGMgRxqCDIRBR7iTY74HacpzrDV0QtERHRKQEk1tq7drZUtHg==",
"version": "0.38.3",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.3.tgz",
"integrity": "sha512-vijevLh06Gtmex6BQzc9jRrGce6La0qnsF4bKwKM2L1ou0/sbJIOAkg7wz6YLLaodnUwQLljIhtrGxnkMjc1Ew==",
"license": "MIT"
},
"node_modules/@discordjs/collection": {
@ -93,9 +93,9 @@
}
},
"node_modules/@discordjs/formatters/node_modules/discord-api-types": {
"version": "0.38.1",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.1.tgz",
"integrity": "sha512-vsjsqjAuxsPhiwbPjTBeGQaDPlizFmSkU0mTzFGMgRxqCDIRBR7iTY74HacpzrDV0QtERHRKQEk1tq7drZUtHg==",
"version": "0.38.3",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.3.tgz",
"integrity": "sha512-vijevLh06Gtmex6BQzc9jRrGce6La0qnsF4bKwKM2L1ou0/sbJIOAkg7wz6YLLaodnUwQLljIhtrGxnkMjc1Ew==",
"license": "MIT"
},
"node_modules/@discordjs/rest": {
@ -134,9 +134,9 @@
}
},
"node_modules/@discordjs/rest/node_modules/discord-api-types": {
"version": "0.38.1",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.1.tgz",
"integrity": "sha512-vsjsqjAuxsPhiwbPjTBeGQaDPlizFmSkU0mTzFGMgRxqCDIRBR7iTY74HacpzrDV0QtERHRKQEk1tq7drZUtHg==",
"version": "0.38.3",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.3.tgz",
"integrity": "sha512-vijevLh06Gtmex6BQzc9jRrGce6La0qnsF4bKwKM2L1ou0/sbJIOAkg7wz6YLLaodnUwQLljIhtrGxnkMjc1Ew==",
"license": "MIT"
},
"node_modules/@discordjs/util": {
@ -187,9 +187,9 @@
}
},
"node_modules/@discordjs/ws/node_modules/discord-api-types": {
"version": "0.38.1",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.1.tgz",
"integrity": "sha512-vsjsqjAuxsPhiwbPjTBeGQaDPlizFmSkU0mTzFGMgRxqCDIRBR7iTY74HacpzrDV0QtERHRKQEk1tq7drZUtHg==",
"version": "0.38.3",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.3.tgz",
"integrity": "sha512-vijevLh06Gtmex6BQzc9jRrGce6La0qnsF4bKwKM2L1ou0/sbJIOAkg7wz6YLLaodnUwQLljIhtrGxnkMjc1Ew==",
"license": "MIT"
},
"node_modules/@sapphire/async-queue": {
@ -226,9 +226,9 @@
}
},
"node_modules/@types/node": {
"version": "22.15.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.2.tgz",
"integrity": "sha512-uKXqKN9beGoMdBfcaTY1ecwz6ctxuJAcUlwE55938g0ZJ8lRxwAZqRz2AJ4pzpt5dHdTPMB863UZ0ESiFUcP7A==",
"version": "22.15.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.10.tgz",
"integrity": "sha512-j2U4KRlgZ9Q8tVO/KDAvXu68vutX4kxoRysL6Q22oEU4ZFT2A16aIyqiIWAwFBZkvKep2UOcSGNoLe/6BI0nrg==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
@ -402,12 +402,12 @@
"license": "MIT"
},
"node_modules/discord.js": {
"version": "14.19.1",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.19.1.tgz",
"integrity": "sha512-r5jsPyaeoCrRGbdse4vQNbHAsoc2zuueyiTFJ2Ce7BiaJak9OldzKZWaWGwKdCFDH3zXlthU1hHXkx1EswKZCA==",
"version": "14.19.3",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.19.3.tgz",
"integrity": "sha512-lncTRk0k+8Q5D3nThnODBR8fR8x2fM798o8Vsr40Krx0DjPwpZCuxxTcFMrXMQVOqM1QB9wqWgaXPg3TbmlHqA==",
"license": "Apache-2.0",
"dependencies": {
"@discordjs/builders": "^1.11.1",
"@discordjs/builders": "^1.11.2",
"@discordjs/collection": "1.5.3",
"@discordjs/formatters": "^0.6.1",
"@discordjs/rest": "^2.5.0",
@ -429,9 +429,9 @@
}
},
"node_modules/discord.js/node_modules/discord-api-types": {
"version": "0.38.1",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.1.tgz",
"integrity": "sha512-vsjsqjAuxsPhiwbPjTBeGQaDPlizFmSkU0mTzFGMgRxqCDIRBR7iTY74HacpzrDV0QtERHRKQEk1tq7drZUtHg==",
"version": "0.38.3",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.3.tgz",
"integrity": "sha512-vijevLh06Gtmex6BQzc9jRrGce6La0qnsF4bKwKM2L1ou0/sbJIOAkg7wz6YLLaodnUwQLljIhtrGxnkMjc1Ew==",
"license": "MIT"
},
"node_modules/dotenv": {
@ -909,9 +909,9 @@
}
},
"node_modules/openai": {
"version": "4.96.0",
"resolved": "https://registry.npmjs.org/openai/-/openai-4.96.0.tgz",
"integrity": "sha512-dKoW56i02Prv2XQolJ9Rl9Svqubqkzg3QpwEOBuSVZLk05Shelu7s+ErRTwFc1Bs3JZ2qBqBfVpXQiJhwOGG8A==",
"version": "4.97.0",
"resolved": "https://registry.npmjs.org/openai/-/openai-4.97.0.tgz",
"integrity": "sha512-LRoiy0zvEf819ZUEJhgfV8PfsE8G5WpQi4AwA1uCV8SKvvtXQkoWUFkepD6plqyJQRghy2+AEPQ07FrJFKHZ9Q==",
"license": "Apache-2.0",
"dependencies": {
"@types/node": "^18.11.18",
@ -939,9 +939,9 @@
}
},
"node_modules/openai/node_modules/@types/node": {
"version": "18.19.87",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.87.tgz",
"integrity": "sha512-OIAAu6ypnVZHmsHCeJ+7CCSub38QNBS9uceMQeg7K5Ur0Jr+wG9wEOEvvMbhp09pxD5czIUy/jND7s7Tb6Nw7A==",
"version": "18.19.94",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.94.tgz",
"integrity": "sha512-6zRqqZiwWiA9nwKamxQzEogpoCf78fpzTOxxBhGDgQci1FJwm3udGjj4NEceGN7CZdJb51iW1+K6z4wcT8gdlQ==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
@ -1178,9 +1178,9 @@
}
},
"node_modules/ws": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz",
"integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==",
"version": "8.18.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz",
"integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"