From a02c28e0879938b8b28fede56100f264861ab0e5 Mon Sep 17 00:00:00 2001 From: quarterturn Date: Sat, 24 May 2025 10:21:28 -0400 Subject: [PATCH] updated messageCreate.ts to fix bot-to-bot cooldowns not working --- src/events/messageCreate.ts | 101 +++++++++++++++++------------------- 1 file changed, 49 insertions(+), 52 deletions(-) diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts index 1ca7043..10a7af7 100644 --- a/src/events/messageCreate.ts +++ b/src/events/messageCreate.ts @@ -48,7 +48,7 @@ const getFriendlyError = () => friendlyErrorResponses[Math.floor(Math.random() * * * @param message the message received from the channel */ -export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client, defaultModel }: { log: (msg: string) => void, msgHist: Queue, ollama: Ollama, client: any, defaultModel: string }, message: Message) => { +export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client, defaultModel }, message: Message) => { // Early check to prevent bot from replying to itself if (!client.user) { log('Client user is not defined. Skipping message processing.') @@ -67,7 +67,7 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client const isBotMessage = message.author.bot && message.author.id !== clientId const isMentioned = message.mentions.has(clientId) const isCommand = message.content.startsWith('/') - const randomChance = Math.random() < 0.1 // 10% chance for non-directed or bot messages + const randomChance = Math.random() < 0.01 // Reduced from 0.1 to 0.01 (1% chance) if (!isMentioned && !isBotMessage && (isCommand || !randomChance)) { log(`Skipping message: isMentioned=${isMentioned}, isBotMessage=${isBotMessage}, isCommand=${isCommand}, randomChance=${randomChance}`) return @@ -87,50 +87,43 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client } } - // Check cooldown for bot-to-bot responses only if probability check passes - const botResponseCooldownKey = `bot:${clientId}:last_bot_response` - const cooldownPeriod = 60 // 60 seconds cooldown - if (isBotMessage && randomChance) { - log(`Bot message probability check passed (10% chance). Checking cooldown.`) + // Check for channel-wide bot-to-bot cooldown + const channelCooldownKey = `channel:${message.channelId}:bot_cooldown` + const cooldownPeriod = 60 // 1 minute + if (isBotMessage) { + log(`Checking bot-to-bot cooldown for channel ${message.channelId}.`) try { - const lastResponseTime = await redis.get(botResponseCooldownKey) + const lastResponseTime = await redis.get(channelCooldownKey) const currentTime = Math.floor(Date.now() / 1000) if (lastResponseTime && (currentTime - parseInt(lastResponseTime)) < cooldownPeriod) { - log(`Bot ${clientId} is in cooldown for bot-to-bot response. Skipping.`) + log(`Channel ${message.channelId} is in bot-to-bot cooldown until ${parseInt(lastResponseTime) + cooldownPeriod}. Skipping.`) return } } catch (error) { - log(`Failed to check bot response cooldown: ${error}`) + log(`Failed to check channel bot-to-bot cooldown: ${error}`) } - } else if (isBotMessage) { - log(`Bot message probability check failed (10% chance). Skipping cooldown check.`) } - // Check if last response was to a bot and require user message - const lastResponseToBotKey = `bot:${clientId}:last_response_to_bot` - let shouldRespond = true + // Check if last message in channel was from a user + const lastMessageTypeKey = `channel:${message.channelId}:last_message_type` if (isBotMessage) { try { - const lastResponseToBot = await redis.get(lastResponseToBotKey) - if (lastResponseToBot === 'true') { - log(`Skipping bot message: Last response was to a bot. Waiting for user message.`) + const lastMessageType = await redis.get(lastMessageTypeKey) + if (lastMessageType !== 'user') { + log(`Skipping bot message: Last message in channel ${message.channelId} was not from a user (type: ${lastMessageType}).`) return } } catch (error) { - log(`Failed to check last response to bot: ${error}`) + log(`Failed to check last message type: ${error}`) } } - if (!shouldRespond) return - - // Reset last_response_to_bot flag if this is a user message - if (!isBotMessage) { - try { - await redis.set(lastResponseToBotKey, 'false') - log(`Reset last_response_to_bot flag for bot ${clientId}`) - } catch (error) { - log(`Failed to reset last_response_to_bot flag: ${error}`) - } + // Update last message type + try { + await redis.set(lastMessageTypeKey, isBotMessage ? 'bot' : 'user', { EX: 3600 }) // 1 hour TTL + log(`Set last_message_type to ${isBotMessage ? 'bot' : 'user'} for channel ${message.channelId}`) + } catch (error) { + log(`Failed to set last message type: ${error}`) } // Log response trigger @@ -170,7 +163,9 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client await new Promise(ret => setTimeout(ret, delay)) } else { log(`Could not retrieve Server Preferences after ${maxRetries} attempts`) - message.reply(getFriendlyError()) + if (!isBotMessage) { // Only reply with error for user messages + message.reply(getFriendlyError()) + } return } } @@ -238,7 +233,9 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client await new Promise(ret => setTimeout(ret, delay)) } else { log(`Could not retrieve User Preferences after ${maxRetries} attempts`) - message.reply(getFriendlyError()) + if (!isBotMessage) { // Only reply with error for user messages + message.reply(getFriendlyError()) + } return } } @@ -268,7 +265,9 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client if (!userConfig) { log(`Failed to initialize User Preference for **${message.author.username}**. No config available.`) - message.reply(getFriendlyError()) + if (!isBotMessage) { // Only reply with error for user messages + message.reply(getFriendlyError()) + } return } @@ -361,7 +360,7 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client } // Log initial sentiments with two decimals - log(`Initial sentiments - User ${message.author.id}: ${userSentiment.toFixed(2)}, Bot: ${botSentiment.toFixed(2)}`) + log(`Initial sentiments - User ${message.author.id}: ${userSentiment.toFixed(2)}, Bot: ${ OLLAMA_NUM_LAYERS=40botSentiment.toFixed(2)}`) // Construct sentiment data for prompt const sentimentData = `User ${message.author.id} sentiment: ${userSentiment.toFixed(2)}, Bot sentiment: ${botSentiment.toFixed(2)}` @@ -395,7 +394,9 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client }) } catch (error) { log(`Ollama chat error: ${error}`) - message.reply(getFriendlyError()) + if (!isBotMessage) { // Only reply with error for user messages + message.reply(getFriendlyError()) + } msgHist.pop() return } @@ -414,14 +415,18 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client } } catch (error) { log(`Failed to parse model response: ${error}`) - message.reply(getFriendlyError()) + if (!isBotMessage) { // Only reply with error for user messages + message.reply(getFriendlyError()) + } msgHist.pop() return } if (jsonResponse.status === 'error') { log(`Model returned error status: ${jsonResponse.reply}`) - message.reply(getFriendlyError()) + if (!isBotMessage) { // Only reply with error for user messages + message.reply(getFriendlyError()) + } msgHist.pop() return } @@ -472,11 +477,12 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client try { await redis.set(`message:${replyMessage.id}:is_bot_response`, 'true', { EX: 3600 }) // 1 hour TTL log(`Marked message ${replyMessage.id} as bot response`) - // Set flag indicating last response was to a bot - await redis.set(lastResponseToBotKey, 'true') - log(`Set last_response_to_bot flag for bot ${clientId}`) + // Set channel-wide bot-to-bot cooldown + const currentTime = Math.floor(Date.now() / 1000) + await redis.set(channelCooldownKey, currentTime.toString(), { EX: cooldownPeriod }) + log(`Set channel ${message.channelId} bot-to-bot cooldown until ${currentTime + cooldownPeriod}`) } catch (error) { - log(`Failed to mark message as bot response or set last_response_to_bot flag: ${error}`) + log(`Failed to mark message as bot response or set channel cooldown: ${error}`) } } @@ -493,20 +499,11 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client } catch (error) { log(`Failed to save channel history to Redis: ${error}`) } - - // Update cooldown timestamp for bot-to-bot response - if (isBotMessage && jsonResponse.status === 'success' && randomChance) { - try { - const currentTime = Math.floor(Date.now() / 1000) - await redis.set(botResponseCooldownKey, currentTime.toString(), { EX: cooldownPeriod }) - log(`Set bot ${clientId} cooldown until ${currentTime + cooldownPeriod}`) - } catch (error) { - log(`Failed to set bot response cooldown: ${error}`) - } - } } catch (error: any) { log(`Error in message processing: ${error.message}`) - message.reply(getFriendlyError()) + if (!isBotMessage) { // Only reply with error for user messages + message.reply(getFriendlyError()) + } msgHist.pop() } })