Skip to content

feat: add free-will message reaction#28

Merged
calebephrem merged 3 commits into
open-devhub:mainfrom
calebephrem:main
Jun 27, 2026
Merged

feat: add free-will message reaction#28
calebephrem merged 3 commits into
open-devhub:mainfrom
calebephrem:main

Conversation

@calebephrem

Copy link
Copy Markdown
Member

No description provided.

@devhub-bot devhub-bot Bot added chore maintenance, configs, formatting, dependencies feat New feature labels Jun 27, 2026
@beetle-ai

beetle-ai Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Summary by Beetle

This PR modernizes the bot's runtime environment by migrating from Node.js to Bun, introduces an autonomous emoji reaction system that allows the AI to react to messages based on sentiment analysis, and applies comprehensive code formatting with Prettier across the entire codebase.

📁 File Changes Summary (Consolidated across all commits):

File Status Changes Description
bun.lock Added +293/-0 New Bun lockfile containing all dependency metadata, replacing the previous package-lock.json. Includes all project dependencies with their versions, peer dependencies, and platform-specific optional dependencies.
src/index.js Modified +6/-4 Reordered imports for consistency, exported the Discord client instance to enable external tool access, and improved the mention-only response message to be more conversational.
src/commands/ai/askai.js Modified +48/-50 Integrated the new react tool into the AI's available tools, added Discord interaction context (channel ID, message ID, interaction type) to the system prompt, and injected comprehensive autonomous reaction instructions that map message sentiment to appropriate emoji reactions.
src/events/messageCreate/handleCommands.js Modified +15/-16 Commented out the automatic command reaction logic (the default 🐾 emoji) to allow the AI's autonomous reaction system to take over instead of having hardcoded reactions.
src/tools/react.js Added +56/-0 New tool that enables the AI to autonomously add emoji reactions to Discord messages by fetching the channel and message via Discord.js API and applying the specified emoji.
docs/superpowers/specs/2026-06-17-session-context-redesign-design.md
eslint.config.js
scripts/smoke-session.mjs
src/commands/ai/model.js
src/commands/ai/persona.js
src/commands/ai/stats.js
src/events/clientReady/setStatus.js
src/events/interactionCreate/modelSelect.js
src/events/interactionCreate/personaSelect.js
src/personas/debugcoach.md
src/personas/flirting.md
src/personas/idea-validator.md
src/personas/index.js
src/personas/interviewer.md
src/personas/motivator.md
src/personas/teenager.md
src/tools/get-stock.js
src/utils/ai.js
src/utils/persona.js
src/utils/session-card.js
src/utils/stats-card.js
src/utils/stock-card.js
src/utils/user-stats.js
Modified +169/-79 Comprehensive Prettier formatting pass: fixed indentation, line breaks, quote consistency, trailing commas, and markdown formatting across all source files, documentation, and persona definitions. No functional changes.

Total Changes: 25 files changed, +587 additions, -145 deletions

🗺️ Walkthrough:

sequenceDiagram
participant User
participant Discord
participant Bot
participant AI Model
participant React Tool
User->>Discord: Sends message mentioning bot
Discord->>Bot: messageCreate event
Bot->>Bot: Parse message & build context
Note over Bot: Includes channelId, messageId, interaction type
Bot->>AI Model: Generate response with tools (search, react, stock, getImage)
AI Model->>AI Model: Analyze message sentiment
Note over AI Model: Funny? Sad? Technical? Frustrating? Wholesome?
alt Message warrants reaction
AI Model->>React Tool: Call react tool with emoji
React Tool->>Discord: Fetch channel & message
React Tool->>Discord: Add emoji reaction
React Tool-->>AI Model: Success confirmation
end
AI Model-->>Bot: Text response + tool results
Bot->>Discord: Send reply to user
Discord->>User: Display response with reaction
Loading

🎯 Key Changes:

  • Runtime Migration to Bun: Switched from Node.js to Bun as the JavaScript runtime, generating a new bun.lock file with all dependency metadata. This change improves startup time and overall performance.
  • Autonomous Emoji Reaction System: The AI can now autonomously react to messages based on sentiment analysis. The system prompt includes detailed instructions mapping message tone to appropriate emojis (😂 for humor, 🔥 for hype, 😭 for sadness, 🤓 for technical content, etc.). The react tool fetches Discord messages via the API and applies reactions dynamically.
  • Context-Aware AI Behavior: The AI now receives Discord interaction context (channel ID, message ID, interaction type: REPLY_TO_YOU, DIRECT_MENTION, or COMMAND_INVOCATION) in the system prompt, enabling more contextually appropriate reactions and responses.
  • Removed Hardcoded Command Reactions: Commented out the automatic 🐾 reaction on command invocations to prevent conflicts with the AI's autonomous reaction system.
  • Code Quality Improvements: Applied Prettier formatting across the entire codebase, improving readability and consistency in JavaScript files, Markdown documentation, and persona definitions.

📊 Impact Assessment:

  • Security: ✅ Low Risk — The react tool only adds emoji reactions and does not expose sensitive data or create security vulnerabilities. The tool validates channel and message existence before attempting reactions. No authentication or permission changes were made.
  • Performance: ✅ Positive Impact — Migrating to Bun improves startup time and runtime performance. The reaction tool adds minimal overhead (one additional API call per reaction). The system prompt is slightly larger (~500 tokens) due to reaction instructions, but this is offset by the removal of hardcoded reaction logic.
  • Maintainability: ✅ Improved — Prettier formatting significantly improves code readability and consistency. The autonomous reaction system is more flexible than hardcoded reactions and can be tuned via prompt engineering. Exporting the client instance from index.js enables better modularity for tools.
  • Testing: ⚠️ Moderate Risk — The autonomous reaction system relies on the AI's sentiment analysis accuracy. Edge cases (ambiguous tone, sarcasm, cultural context) may result in inappropriate or missing reactions. The system should be monitored in production to ensure reaction quality. No automated tests were added for the reaction tool.
⚙️ Settings

Severity Threshold: Medium — Balanced feedback — medium and high severity issues only.Change in Settings
Custom Rules: Define your own review rules — Set Custom Rules
PR Summary: Configure PR summary — Change in Settings

📖 User Guide
  • Once repos are connected, PR analysis is automatically enabled. You can disable analysis for this repo from beetleai.dev/analysis
  • Comment @beetle on any PR to start analysis manually
  • Comment @beetle stop to stop any ongoing analysis

Follow us: Beetle · X · LinkedIn

Comment thread src/commands/ai/askai.js
Comment on lines +512 to +535
// Inject user interaction properties so the model can freely match reactions to message tone
if (currentContext) {
sections.push(
`[Discord Direct Conversation Context]\n` +
`- Channel ID: ${currentContext.channelId}\n` +
`- Target Message ID: ${currentContext.messageId}\n` +
`- Interaction Hook: ${currentContext.interactionType}\n\n` +
`[Autonomous Reactions Instructions]:\n` +
`You are explicitly authorized to use the 'react' tool autonomously on the incoming user message if its tone, content, or context warrants an emotional reaction. Read the sentiment carefully:\n` +
`- If the message is genuinely funny, humorous, or witty → React with '😂', '🤣', or '💀'.\n` +
`- If the message contains obvious flame bait, trolling, or friendly sarcasm → React with '🤨', '🤡', or '😡'.\n` +
`- If the message shows hype, an achievement, or excellent news → React with '🔥', '🚀', or '🙌'.\n` +
`- If the message is sad, unfortunate, moving, or a "feels bad man" moment → React with '😭', '🥺', or '💔'.\n` +
`- If the message is highly technical, detailed, a deep-dive, or full of "nerd" energy → React with '🤓', '🧠', or '📝'.\n` +
`- If the message is completely bizarre, confusing, or leaves you speechless → React with '🤔', '❓', or '🫠'.\n` +
`- If the message mentions a catastrophic bug, a production crash, or scary code → React with '😱', '😨', or '💥'.\n` +
`- If the message is wholesome, genuinely kind, or expresses warm appreciation → React with '❤️', '🥰', or '✨'.\n` +
`- If the message expresses sheer frustration, annoying blockers, or unhelpful errors → React with '😤', '🤬', or '💢'.\n` +
`- If the message talks about being burnt out, working late hours, or being completely exhausted → React with '😴', '😮‍💨', or '🥱'.\n` +
`- If the user shares something highly unexpected, wild gossip, or mind-blowing tech news → React with '🤯', '😲', or '👁️‍🗨️'.\n` +
`- If it's a routine query or structured setup, you can skip the tool call entirely.\n` +
`Execute the 'react' tool dynamically before finalizing your text response when applicable.`,
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The autonomous reactions system prompt is extremely verbose (24+ lines of detailed emoji mapping instructions). This has several problems:

  1. Token Cost: This massive prompt will be sent with every AI request, consuming significant tokens and increasing API costs
  2. Maintainability: Hardcoded emoji mappings in a giant template literal are difficult to maintain and update
  3. Prompt Injection Risk: The extensive instructions about autonomous behavior could be manipulated by carefully crafted user messages
  4. Performance: The AI model must process this entire instruction set on every request, even for simple queries

Confidence: 5/5

Suggested Fix

Consider refactoring this to:

  • Extract emoji mappings to a configuration object
  • Generate the prompt dynamically from the config
  • Make the instructions more concise (e.g., "React with appropriate emojis based on message sentiment")
  • Consider moving detailed mappings to a separate training/fine-tuning approach rather than prompt engineering
    Example approach:
const REACTION_GUIDE = {
funny: ['😂', '🤣', '💀'],
trolling: ['🤨', '🤡', '😡'],
// ... other categories
};
// Then generate a much shorter prompt:
const reactionPrompt = `You may use the 'react' tool to add emoji reactions based on message sentiment. Available categories: ${Object.keys(REACTION_GUIDE).join(', ')}`;
Prompt for AI

Copy this prompt to your AI IDE to fix this issue locally:

In src/commands/ai/askai.js around lines 512-535, refactor the extremely verbose
autonomous reactions system prompt to reduce token costs and improve maintainability.
Extract the emoji mappings to a configuration object, generate a concise prompt
dynamically, and consider whether all these detailed instructions need to be in
every API call or could be simplified to "React with appropriate emojis based on
message sentiment and tone."

📍 This suggestion applies to lines 512-535

Comment thread src/commands/ai/askai.js
);

const isReplyToBot = message.reference?.messageId ? true : false;
const mentionsBot = message.mentions.has(client.user);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code assumes client.user is always defined, but if the client hasn't fully initialized or there's a connection issue, this could throw a runtime error. This would crash the command handler.

Confidence: 4/5

Suggested Fix
Suggested change
const mentionsBot = message.mentions.has(client.user);
const mentionsBot = client.user ? message.mentions.has(client.user) : false;

Add a null check to prevent potential crashes if client.user is undefined during edge cases like bot startup or reconnection scenarios.

Prompt for AI

Copy this prompt to your AI IDE to fix this issue locally:

In src/commands/ai/askai.js around line 139, add a null check for client.user
before calling message.mentions.has(client.user) to prevent potential runtime
errors during bot initialization or connection issues. Use:
`const mentionsBot = client.user ? message.mentions.has(client.user) : false;`

Comment thread src/tools/react.js
Comment on lines +24 to +41
const channel = await client.channels.fetch(channelId);

if (!channel || !channel.isTextBased()) {
return {
success: false,
error: "Channel not found or is not a text-based channel.",
};
}

// 2. Fetch the specific message
const discordMessage = await channel.messages.fetch(messageId);

if (!discordMessage) {
return { success: false, error: "Message not found." };
}

// 3. React to the message
await discordMessage.react(emoji);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing permission checks before attempting to react to messages. If the bot lacks ADD_REACTIONS permission in the channel, the react() call will throw an error. This could cause the tool to fail unexpectedly and return a generic error message instead of a clear permission error.

Confidence: 5/5

Suggested Fix

Add permission checks before attempting to fetch and react to messages:

Suggested change
const channel = await client.channels.fetch(channelId);
if (!channel || !channel.isTextBased()) {
return {
success: false,
error: "Channel not found or is not a text-based channel.",
};
}
// 2. Fetch the specific message
const discordMessage = await channel.messages.fetch(messageId);
if (!discordMessage) {
return { success: false, error: "Message not found." };
}
// 3. React to the message
await discordMessage.react(emoji);
// 1. Fetch the channel from the Discord client cache or API
const channel = await client.channels.fetch(channelId);
if (!channel || !channel.isTextBased()) {
return {
success: false,
error: "Channel not found or is not a text-based channel.",
};
}
// Check if bot has permission to add reactions
if (!channel.permissionsFor(client.user)?.has('AddReactions')) {
return {
success: false,
error: "Bot does not have permission to add reactions in this channel.",
};
}
// 2. Fetch the specific message
const discordMessage = await channel.messages.fetch(messageId);
if (!discordMessage) {
return { success: false, error: "Message not found." };
}
// 3. React to the message
await discordMessage.react(emoji);

This prevents runtime errors and provides clear feedback when permissions are missing.

Prompt for AI

Copy this prompt to your AI IDE to fix this issue locally:

In src/tools/react.js around lines 24-41, add a permission check after fetching
the channel to verify the bot has 'AddReactions' permission before attempting to
react to messages. Use `channel.permissionsFor(client.user)?.has('AddReactions')`
and return a clear error message if the permission is missing, preventing runtime
errors and providing better user feedback.

📍 This suggestion applies to lines 24-41

@calebephrem calebephrem merged commit b205d7d into open-devhub:main Jun 27, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore maintenance, configs, formatting, dependencies feat New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant