-
Notifications
You must be signed in to change notification settings - Fork 4
Bot stealth #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Bot stealth #20
Conversation
… quality and organization - Added `import-x` plugin and TypeScript resolver to ESLint configuration. - Updated dependencies in `package.json` and `bun.lock` for ESLint and Prettier plugins. - Refactored imports in `discord.ts` and `stream.ts` for better organization and clarity.
…ty and consistency - Adjusted import statements in `deploy-commands.ts`, `index.ts`, and various command files to enhance readability. - Ensured consistent ordering of imports in `message-create` event handlers and utility files. - Removed redundant imports and streamlined code structure in several modules.
…ell checking - Corrected spelling for "ASSEMBLYAI" to "assemblyai" and "ELEVENLABS" to "ElevenLabs". - Added new entries "HackClub" and "OpenRouter" to the cSpell dictionary.
…ence - Commented out the `hackclub`, `openrouter`, and `google` provider configurations in `providers.ts` to prevent unused code while maintaining the option to re-enable them later.
…ders.ts - Removed unused import statements for `env`, `createGoogleGenerativeAI`, `createOpenAICompatible`, and `createOpenRouter` to clean up the code and improve maintainability.
…ment configuration
…nse prompts for better user interaction
…language model references
…e in Discord tool
…th new initial messagesa
…th new initial messagesa
…evance and replies
WalkthroughThis update migrates the Discord bot from Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DiscordSelfbot
participant AIProvider
participant Pinecone
User->>DiscordSelfbot: Sends message
DiscordSelfbot->>DiscordSelfbot: Detects trigger (async)
alt If trigger detected
DiscordSelfbot->>DiscordSelfbot: Build chat context (fetch messages, hints)
DiscordSelfbot->>AIProvider: Generate response (with tools)
AIProvider->>Pinecone: (If tool: searchMemories) Query vector DB
Pinecone-->>AIProvider: Return memory results
AIProvider-->>DiscordSelfbot: Return response
DiscordSelfbot->>User: Reply with AI response
DiscordSelfbot->>Pinecone: Add conversation as memory
end
Estimated code review effort🎯 5 (Critical) | ⏱️ ~90 minutes Possibly related PRs
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 36
🔭 Outside diff range comments (3)
.github/actions/setup/action.yml (1)
1-43
: YAML uses CRLF – breaks lint rule & cross-platform diffsThe workflow is committed with
\r\n
line endings, triggering the YAML-lint complaint and causing noisy diffs on Unix hosts. Convert to LF (\n
) or add an.editorconfig
override for*.yml
to keep line endings consistent..github/workflows/ci.yml (1)
1-60
: LGTM - Formatting improvements appliedThe whitespace and formatting changes improve readability while maintaining all functionality.
Consider addressing the static analysis issues:
- Add a description to the setup action metadata in
.github/actions/setup/action.yml
- Fix the YAML newline character format
- Review the truthy value on line 3
+name: CI + on: pull_request: branches: - mainsrc/utils/status.ts (1)
1-69
: Critical: Remove selfbot usage (discord.js-selfbot-v13) – violates Discord TOSYour code currently uses a self-bot library (
discord.js-selfbot-v13
), which is explicitly prohibited by Discord’s Terms of Service and Platform Manipulation Policy and can lead to account termination. Please switch to a proper bot account and the officialdiscord.js
library.Please address the following in your PR:
• In
src/utils/status.ts
:
- Replace
with imports fromimport type { ActivityType, PresenceStatusData } from 'discord.js-selfbot-v13'; import { Client, RichPresence } from 'discord.js-selfbot-v13';discord.js
.- Ensure you instantiate
Client
with a bot token, not a user token.• Client initialization (wherever you log in):
- Use
client.login(BOT_TOKEN)
instead of providing a user token.• Rich presence & assets:
- If you need custom activity assets, migrate to the official
discord.js
methods or the Discord API endpoints available to bot accounts.Recommendations:
- Use a bot account created via the Discord Developer Portal and the standard
discord.js
package.- For any user-specific functionality, leverage OAuth2 flows rather than automating a user account.
- Document in your README that this change was made to comply with Discord’s policies.
♻️ Duplicate comments (1)
src/utils/messages.ts (1)
8-8
: Import resolution error (same as index.ts)The module 'discord.js-selfbot-v13' cannot be resolved. This is the same issue as in index.ts.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (61)
.cspell.json
(1 hunks).editorconfig
(1 hunks).env.example
(1 hunks).eslintrc.json
(1 hunks).github/FUNDING.yml
(1 hunks).github/actions/setup/action.yml
(1 hunks).github/pull-request-template.md
(1 hunks).github/workflows/ci.yml
(1 hunks).prettierrc.json
(0 hunks)README.md
(1 hunks)TODO.md
(1 hunks)commitlint.config.ts
(1 hunks)package.json
(1 hunks)src/commands/channels.ts
(0 hunks)src/commands/chat.ts
(0 hunks)src/commands/index.ts
(1 hunks)src/commands/ping.ts
(1 hunks)src/commands/voice-channel/index.ts
(1 hunks)src/commands/voice-channel/join.ts
(1 hunks)src/commands/voice-channel/leave.ts
(1 hunks)src/config.ts
(1 hunks)src/deploy-commands.ts
(0 hunks)src/env.ts
(1 hunks)src/events/index.ts
(1 hunks)src/events/message-create/index.ts
(1 hunks)src/events/message-create/utils/relevance.ts
(1 hunks)src/events/message-create/utils/respond.ts
(1 hunks)src/index.ts
(1 hunks)src/lib/ai/prompts.ts
(1 hunks)src/lib/ai/providers.ts
(1 hunks)src/lib/ai/tools/discord.ts
(0 hunks)src/lib/ai/tools/get-weather.ts
(1 hunks)src/lib/ai/tools/report.ts
(1 hunks)src/lib/ai/tools/search-web.ts
(1 hunks)src/lib/kv.ts
(1 hunks)src/lib/logger.ts
(1 hunks)src/lib/queries.ts
(1 hunks)src/lib/search.ts
(1 hunks)src/lib/validators/index.ts
(1 hunks)src/lib/validators/probability.ts
(1 hunks)src/types/activity.ts
(1 hunks)src/types/index.ts
(1 hunks)src/types/message.ts
(1 hunks)src/types/request.ts
(1 hunks)src/utils/context.ts
(1 hunks)src/utils/delay.ts
(1 hunks)src/utils/discord.ts
(1 hunks)src/utils/log.ts
(1 hunks)src/utils/message-rate-limiter.ts
(1 hunks)src/utils/messages.ts
(1 hunks)src/utils/sandbox.ts
(0 hunks)src/utils/status.ts
(1 hunks)src/utils/time.ts
(1 hunks)src/utils/tokenize-messages.ts
(1 hunks)src/utils/triggers.ts
(1 hunks)src/utils/voice/helpers/ai.ts
(1 hunks)src/utils/voice/helpers/audio.ts
(1 hunks)src/utils/voice/helpers/deepgram.ts
(1 hunks)src/utils/voice/helpers/index.ts
(1 hunks)src/utils/voice/stream.ts
(1 hunks)tsconfig.json
(1 hunks)
💤 Files with no reviewable changes (6)
- .prettierrc.json
- src/deploy-commands.ts
- src/commands/channels.ts
- src/utils/sandbox.ts
- src/commands/chat.ts
- src/lib/ai/tools/discord.ts
🧰 Additional context used
🧬 Code Graph Analysis (18)
src/lib/search.ts (1)
src/env.ts (1)
env
(4-55)
src/lib/ai/tools/report.ts (1)
src/utils/messages.ts (1)
MinimalContext
(10-10)
src/utils/voice/helpers/ai.ts (2)
src/lib/ai/prompts.ts (1)
regularPrompt
(18-33)src/lib/ai/providers.ts (1)
myProvider
(21-33)
src/utils/delay.ts (1)
src/utils/tokenize-messages.ts (2)
normalize
(9-11)sentences
(1-7)
src/lib/logger.ts (1)
src/env.ts (1)
env
(4-55)
src/lib/ai/tools/search-web.ts (1)
src/lib/search.ts (1)
exa
(10-10)
src/utils/log.ts (1)
src/utils/triggers.ts (1)
TriggerType
(3-3)
src/utils/message-rate-limiter.ts (2)
src/lib/kv.ts (2)
redisKeys
(19-22)redis
(7-10)src/config.ts (1)
messageThreshold
(49-49)
src/utils/voice/helpers/deepgram.ts (1)
src/env.ts (1)
env
(4-55)
src/lib/kv.ts (1)
src/env.ts (1)
env
(4-55)
src/utils/time.ts (1)
src/config.ts (1)
timezone
(7-7)
src/lib/ai/providers.ts (1)
src/env.ts (1)
env
(4-55)
src/commands/ping.ts (3)
src/commands/voice-channel/index.ts (2)
data
(9-25)execute
(27-41)src/commands/voice-channel/join.ts (2)
data
(12-16)execute
(18-66)src/commands/voice-channel/leave.ts (2)
data
(5-9)execute
(11-36)
src/utils/triggers.ts (1)
src/config.ts (1)
keywords
(4-4)
src/commands/voice-channel/leave.ts (3)
src/commands/voice-channel/index.ts (2)
data
(9-25)execute
(27-41)src/commands/ping.ts (2)
data
(4-8)execute
(10-12)src/commands/voice-channel/join.ts (2)
data
(12-16)execute
(18-66)
src/utils/context.ts (5)
src/utils/messages.ts (1)
convertToModelMessages
(12-35)src/types/request.ts (1)
RequestHints
(3-12)src/lib/queries.ts (2)
getMessagesByChannel
(11-28)getChannelName
(30-42)src/utils/time.ts (1)
getTimeInCity
(4-11)src/config.ts (1)
timezone
(7-7)
src/utils/status.ts (3)
src/index.ts (1)
client
(7-7)src/config.ts (2)
statuses
(16-16)activities
(18-47)src/types/activity.ts (1)
Activity
(1-5)
src/config.ts (1)
src/types/activity.ts (1)
Activity
(1-5)
🪛 LanguageTool
README.md
[locale-violation] ~28-~28: In American English, ‘afterward’ is the preferred variant. ‘Afterwards’ is more commonly used in British English and other dialects.
Context: ...idpolice.com/how-to-make-discord-bot/). Afterwards, you will need Git and Bun[bun...
(AFTERWARDS_US)
[grammar] ~52-~52: Use correct spacing
Context: ...t to Fellipe Utaka for the Discord Bot Template
(QB_NEW_EN_OTHER_ERROR_IDS_5)
.github/pull-request-template.md
[style] ~9-~9: Consider using a different verb for a more formal wording.
Context: ... [ ] Bug fix (non-breaking change which fixes an issue)
- New feature (non-break...
(FIX_RESOLVE)
TODO.md
[style] ~13-~13: The phrasing ‘more easy’ can sound awkward and informal. Consider using a comparative adjective or other alternative.
Context: ...).
Refactor the channels command to be more easy to use, with deny and allow lists.
D...
(MORE_EASY_N_CLEAR)
[grammar] ~29-~29: Use correct spacing
Context: ...ous messages, and maintain context over time.
Look into CrewAI or build your own custo...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
🪛 markdownlint-cli2 (0.17.2)
README.md
1-1: Inline HTML
Element: h1
(MD033, no-inline-html)
10-10: Inline HTML
Element: a
(MD033, no-inline-html)
14-14: Inline HTML
Element: a
(MD033, no-inline-html)
26-26: Inline HTML
Element: a
(MD033, no-inline-html)
48-48: Inline HTML
Element: a
(MD033, no-inline-html)
54-54: Link and image reference definitions should be needed
Unused link or image reference definition: "pr"
(MD053, link-image-reference-definitions)
56-56: Link and image reference definitions should be needed
Unused link or image reference definition: "node"
(MD053, link-image-reference-definitions)
.github/pull-request-template.md
1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🪛 ESLint
src/lib/search.ts
[error] 2-2: Unable to resolve path to module 'exa-js'.
(import-x/no-unresolved)
src/lib/ai/tools/get-weather.ts
[error] 1-1: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 2-2: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/lib/ai/tools/report.ts
[error] 3-3: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/utils/voice/helpers/ai.ts
[error] 3-3: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
src/lib/validators/probability.ts
[error] 1-1: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/utils/delay.ts
[error] 8-8: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/lib/logger.ts
[error] 5-5: Unable to resolve path to module 'pino'.
(import-x/no-unresolved)
src/lib/queries.ts
[error] 9-9: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/lib/ai/tools/search-web.ts
[error] 3-3: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/utils/voice/helpers/deepgram.ts
[error] 2-2: Unable to resolve path to module '@deepgram/sdk'.
(import-x/no-unresolved)
src/utils/voice/helpers/audio.ts
[error] 6-6: Unable to resolve path to module '@discordjs/voice'.
(import-x/no-unresolved)
src/lib/kv.ts
[error] 2-2: Unable to resolve path to module '@upstash/ratelimit'.
(import-x/no-unresolved)
[error] 3-3: Unable to resolve path to module '@upstash/redis'.
(import-x/no-unresolved)
src/utils/time.ts
[error] 1-1: Unable to resolve path to module '@date-fns/tz'.
(import-x/no-unresolved)
[error] 2-2: Unable to resolve path to module 'date-fns'.
(import-x/no-unresolved)
src/utils/voice/stream.ts
[error] 3-3: Unable to resolve path to module '@deepgram/sdk'.
(import-x/no-unresolved)
[error] 8-8: Unable to resolve path to module '@discordjs/voice'.
(import-x/no-unresolved)
[error] 10-10: Unable to resolve path to module 'prism-media'.
(import-x/no-unresolved)
src/env.ts
[error] 1-1: Unable to resolve path to module '@t3-oss/env-core'.
(import-x/no-unresolved)
[error] 2-2: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/lib/ai/providers.ts
[error] 1-1: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module '@ai-sdk/google'.
(import-x/no-unresolved)
[error] 5-5: Unable to resolve path to module '@ai-sdk/openai'.
(import-x/no-unresolved)
src/commands/ping.ts
[error] 2-2: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/commands/voice-channel/index.ts
[error] 5-5: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/events/message-create/utils/relevance.ts
[error] 4-4: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
src/events/message-create/utils/respond.ts
[error] 9-9: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
src/utils/triggers.ts
[error] 1-1: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/utils/discord.ts
[error] 4-4: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/commands/voice-channel/leave.ts
[error] 1-1: Unable to resolve path to module '@discordjs/voice'.
(import-x/no-unresolved)
[error] 3-3: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/utils/context.ts
[error] 7-7: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/utils/status.ts
[error] 4-4: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/utils/messages.ts
[error] 8-8: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/commands/voice-channel/join.ts
[error] 8-8: Unable to resolve path to module '@discordjs/voice'.
(import-x/no-unresolved)
[error] 10-10: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/events/message-create/index.ts
[error] 10-10: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/index.ts
[error] 5-5: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
🪛 YAMLlint (1.37.1)
.github/actions/setup/action.yml
[error] 1-1: wrong new line character: expected \n
(new-lines)
.github/FUNDING.yml
[error] 1-1: wrong new line character: expected \n
(new-lines)
.github/workflows/ci.yml
[error] 1-1: wrong new line character: expected \n
(new-lines)
[warning] 3-3: truthy value should be one of [false, true]
(truthy)
🪛 GitHub Actions: CI
src/lib/ai/providers.ts
[warning] 18-18: ESLint warning: Forbidden non-null assertion (@typescript-eslint/no-non-null-assertion). ESLint found too many warnings (maximum: 0).
src/events/message-create/utils/relevance.ts
[error] 1-1: TypeScript error TS2459: Module '@lib/ai/prompts' declares 'RequestHints' locally, but it is not exported.
src/utils/context.ts
[error] 2-2: TypeScript error TS2459: Module '@lib/ai/prompts' declares 'RequestHints' locally, but it is not exported.
🪛 actionlint (1.7.7)
.github/workflows/ci.yml
17-17: description is required in metadata of "Check setup" action at "/home/jailuser/git/.github/actions/setup/action.yml"
(action)
🔇 Additional comments (49)
commitlint.config.ts (1)
1-1
: Whitespace-only change looks goodNo functional or stylistic concerns with this single-line whitespace tweak.
src/lib/validators/index.ts (1)
1-1
: Export statement unchanged – OKThe whitespace normalization does not affect behaviour. ✅
src/lib/search.ts (1)
1-3
: No action needed:exa-js
is already declaredThe
exa-js
package appears underdependencies
inpackage.json
(version ^1.8.12), so the import insrc/lib/search.ts
will resolve correctly at build/runtime.src/utils/voice/helpers/index.ts (1)
1-3
: No-op line-ending changeExports remain intact; nothing else to flag.
src/lib/logger.ts (2)
18-20
: Top-levelawait
– verify Node/bundler supportThe
await mkdir(...)
call executes in module scope. This requires:• the emitted file to stay ESM
• a Node v16.8+ (or bundler equivalent) runtime that supports top-level await.If consumers transpile to CommonJS, the build will fail. Double-check build targets or wrap the block in an IIFE:
(async () => { if (!(await exists(logDir))) { await mkdir(logDir, { recursive: true }); } })();
1-5
: pino dependency confirmed in package.jsonThe
pino
module is listed underdependencies
(“pino”: “^9.6.0”), so runtime resolution won’t fail. No further action needed.src/utils/log.ts (1)
4-14
: Formatting-only change looks goodNo functional impact; logging behaviour unchanged.
README.md (2)
19-19
: Remove Mem0 reference is consistent with codebase changes.The removal of Mem0 from the tech stack aligns with the broader removal of Mem0-related environment variables and references throughout the codebase.
50-50
: License change from AGPL-v3 to MIT appears intentional.This change relaxes the licensing terms, which may be intentional for the selfbot architecture migration.
.cspell.json (1)
34-37
: Spell checker updates align with codebase migration.The addition of selfbot-related terminology ("selfbot", "autobotting") and persona-related terms ("shitposter", "cynicist") appropriately supports the migration to selfbot architecture and the new "Gork" persona.
src/lib/ai/tools/search-web.ts (1)
1-34
: Formatting changes maintain functionality.The modifications are limited to formatting adjustments with no changes to the search functionality. The tool continues to serve its purpose in the simplified AI tooling ecosystem after removing the Discord automation tool.
TODO.md (1)
34-34
: TODO item appropriately documents migration impact.The addition of "Fix commands (broken on autobotting)" correctly acknowledges a known issue resulting from the migration to selfbot architecture, where existing commands may need adaptation.
src/lib/kv.ts (1)
19-22
: Redis key removal aligns with command deletion.The removal of the
allowedChannels
key is consistent with the deletion of the channels command and the elimination of channel allowance logic from the message processing system..env.example (1)
43-43
: LGTM - Consistent with Mem0 removal.The commenting out of
MEM0_API_KEY
aligns with the broader removal of memory-based AI features from the codebase.src/types/activity.ts (1)
1-5
: LGTM - Clean interface definition.The
Activity
interface is well-structured and provides a clear contract for activity objects with appropriate typing.src/utils/message-rate-limiter.ts (1)
1-19
: LGTM - Formatting improvements with no functional changes.The rate limiting logic remains intact and properly configured with Redis expiry and threshold checks.
src/utils/time.ts (1)
6-6
: LGTM - Minor syntax improvement.Removing the trailing comma from the default parameter improves code cleanliness.
src/utils/voice/helpers/audio.ts (1)
1-7
:@discordjs/voice
may not resolve in Bun – verify build pathES Lint reports
import-x/no-unresolved
. With the migration todiscord.js-selfbot-v13
, double-check that:
@discordjs/voice
is still present innode_modules
after switching to Bun.- Your
tsconfig
/bunfig
paths allow Node-style resolution.If compatibility issues arise, replace the import with a Bun-friendly voice wrapper or remove voice features (self-bots can’t join VC anyway – see next comment).
src/utils/voice/helpers/deepgram.ts (1)
1-4
: Same unresolved-import issue as above
@deepgram/sdk
path not resolved per ESLint. Ensure it exists innode_modules
and that Bun’s resolution picks it up; otherwise add it to dependencies.src/commands/index.ts (1)
1-7
: Breaking change: Command functionality significantly reducedThe removal of
channels
andchat
commands represents a substantial reduction in bot functionality. While this aligns with the migration to a selfbot architecture, this is a breaking change that should be clearly documented.The selfbot architecture change has legal and ToS implications - ensure this migration complies with Discord's Terms of Service regarding automated user accounts.
src/utils/delay.ts (1)
3-8
: Import migration completed correctlyThe migration from
discord.js
todiscord.js-selfbot-v13
is implemented correctly while preserving all functionality.The human-like behavior simulation (typing indicators, randomized delays, punctuation-based pauses) may increase detectability of automated behavior. Ensure this aligns with your intended selfbot usage patterns and consider Discord's stance on automated user accounts.
src/env.ts (1)
4-55
: Environment schema correctly updated for selfbot architectureThe removal of
DISCORD_CLIENT_ID
andMEM0_API_KEY
appropriately reflects the migration from bot to selfbot architecture. Selfbots authenticate with user tokens and don't require client IDs.The removal of
MEM0_API_KEY
indicates that AI memory features have been eliminated as part of this simplification. Ensure this aligns with your intended feature set.src/utils/voice/stream.ts (1)
9-9
: Import migration completed correctlyThe migration of the
User
type import fromdiscord.js
todiscord.js-selfbot-v13
is implemented correctly while preserving all voice streaming functionality.Voice functionality in selfbots may be particularly detectable and could violate Discord's Terms of Service. The automated voice processing, transcription, and AI response generation creates a sophisticated bot-like behavior that may be easily identified. Consider the legal and ToS implications of automated voice interactions on user accounts.
src/types/request.ts (1)
3-12
: Well-structured interface for AI context.The
RequestHints
interface provides comprehensive contextual information for AI requests. The use ofGeo
types from@vercel/functions
for location data is appropriate.Consider whether all properties should be required - some like
activity
might not always be available and could be optional.src/lib/ai/providers.ts (1)
25-27
: Confirmed: ‘gemini-2.5-flash’ Is a Valid Model IdentifierThe Google Gemini 2.5 Flash series offers three variants—Flash-Lite, Flash (standard), and Pro—each with distinct trade-offs:
- Flash-Lite (gemini-2.5-flash-lite): Ultra low-latency, cost-efficient for real-time apps
- Flash (gemini-2.5-flash): Adaptive thinking and high-volume processing (standard use case for chat/reasoning)
- Pro (gemini-2.5-pro): Enhanced reasoning and analysis for deep-dive tasks
Your use of
google('gemini-2.5-flash')
correctly targets the standard Flash model. No changes are required.src/utils/discord.ts (2)
1-4
: Successful migration to selfbot library.The migration from
discord.js
EmbedBuilder
todiscord.js-selfbot-v13
MessageEmbed
is correctly implemented while preserving all functionality.
30-32
: Compatibility Confirmed: MessageEmbed API matches discord.js-selfbot-v13The
MessageEmbed
class indiscord.js-selfbot-v13
is a direct backport of v13’s embed builder and supports all of the following methods used inmakeEmbed
without breaking changes:
setTitle()
setDescription()
setColor()
addFields()
No further action is needed here.
src/events/message-create/utils/relevance.ts (1)
7-11
: Successful removal of memory functionality.The function signature correctly removes the
memories
parameter, aligning with the broader simplification of the AI system.src/commands/ping.ts (2)
4-8
: Proper command data structure for selfbot.The migration from
SlashCommandBuilder
to plainApplicationCommandData
object is correct for the selfbot architecture. The explicittype: 1
for ChatInput command is properly specified.
10-12
: Command execution logic preserved correctly.The function signature update to use
CommandInteraction
fromdiscord.js-selfbot-v13
is appropriate, and the simple reply logic remains intact.src/utils/tokenize-messages.ts (1)
1-7
: Verify regex pattern handles all sentence splitting edge cases.The custom regex implementation replaces the
compromise
NLP library. While this reduces dependencies, it may not handle all edge cases the library previously covered (e.g., abbreviations, decimal numbers, quoted text).Consider adding comprehensive tests to ensure the regex properly handles:
- Abbreviations (e.g., "Dr.", "Mr.", "etc.")
- Decimal numbers (e.g., "3.14")
- Quoted sentences
- Multiple consecutive punctuation marks
The lookbehind assertion
(?<=...)
requires ES2018+ support. Ensure your target environment supports this feature.src/events/message-create/utils/respond.ts (1)
11-42
: Good simplification of response generation.The removal of memories and dynamic tool selection simplifies the function and makes it more maintainable. The fixed set of tools (getWeather, searchWeb, report) provides a clear, predictable behavior.
src/commands/voice-channel/leave.ts (2)
5-9
: Command data structure looks good.The
ApplicationCommandData
export follows the consistent pattern used across other commands in the selfbot migration.
11-36
: Well-implemented voice channel leave logic.The function correctly:
- Validates guild context before processing
- Uses ephemeral replies for all responses
- Handles the case when the bot is not in a voice channel
- Properly destroys the voice connection
src/utils/context.ts (1)
9-40
: Clean refactoring of context building logic.The function has been successfully simplified by removing memory handling. The implementation correctly:
- Fetches messages from the channel with a reasonable limit
- Builds comprehensive hints with safe fallbacks using nullish coalescing
- Maintains type safety with the Channel assertion
src/types/message.ts (1)
1-33
: Well-designed minimal context interface.The
MinimalContext
interface provides a clean abstraction for message handling in the selfbot architecture. It includes all essential properties while maintaining type safety with the comprehensive channel union type.src/events/message-create/index.ts (3)
1-20
: Event configuration properly updated for selfbot.The migration correctly updates the event name to a string format and maintains all necessary imports for the message handling logic.
42-84
: Clean removal of memory handling from response flow.The refactored code successfully:
- Removes memory parameters from all context and response generation calls
- Maintains proper rate limiting and relevance checking
- Preserves the distinction between triggered and relevance-based responses
29-41
: Selfbot message filtering and async trigger handling verified
- The selfbot check (
message.author.id === message.client.user?.id
) correctly prevents the bot from processing its own messages.- Confirmed
getTrigger
is declared asasync function getTrigger
insrc/utils/triggers.ts
, matching the awaited call.No further changes required.
src/commands/voice-channel/join.ts (3)
1-16
: Command structure follows the established selfbot pattern.The imports and command data definition are consistent with other voice commands in the migration.
18-35
: Robust validation and member state handling.The implementation correctly:
- Validates guild context before proceeding
- Fetches fresh member data to ensure accurate voice state
- Provides clear feedback when the user is not in a voice channel
37-66
: Well-implemented voice connection and audio handling.The code correctly:
- Configures voice connection with appropriate selfbot settings
- Sets up audio player and receiver for listening functionality
- Handles errors gracefully with informative user messages
src/index.ts (3)
29-35
: Good addition of error handling for eventsThe try-catch wrapper around event execution prevents unhandled errors from crashing the bot. This is a solid improvement for stability.
44-46
: Good addition of login error handlingAdding error handling for the login process helps with debugging connection issues.
5-5
: Ensure module resolution by installing dependencies
Thediscord.js-selfbot-v13
package is already declared in your package.json, so the import in src/index.ts is correct. The “module can’t be resolved” error occurs because the package isn’t installed (and no lockfile is committed).• Run your install command (e.g.
npm install
,yarn install
orpnpm install
) before building or linting.
• Commit the generated lockfile (package-lock.json
,yarn.lock
orpnpm-lock.yaml
) to the repo root so CI and teammates install the same dependencies.
• Re-run static analysis; the import should then resolve without errors.src/utils/messages.ts (1)
17-27
: Good improvement to include referenced messagesIncluding referenced message content as quoted text provides better context for the AI model. The formatting with author usernames is clean and readable.
src/config.ts (1)
50-131
: Verify appropriateness of message contentThe initial messages contain profanity and potentially inappropriate content. Ensure this aligns with the intended use case and won't violate community guidelines where the bot operates.
src/lib/ai/prompts.ts (2)
19-33
: Verify the intent behind giving wrong answersThe prompt instructs the AI to "always give wrong answers" to serious questions. This could be problematic if users rely on the bot for any factual information, even inadvertently.
Consider adding a disclaimer in the bot's status or profile to indicate it's designed for entertainment only.
31-33
: Good use of config for example messagesUsing
initialMessages
from the config ensures the prompt examples stay synchronized with the actual configured messages.
insert_final_newline = true | ||
quote_type = single | ||
|
||
[*.md] | ||
trim_trailing_whitespace = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Non-standard quote_type
may be ignored by tools
quote_type
is not part of the EditorConfig core spec.
Unless every contributor’s editor has a custom plugin that understands this key, the rule will silently be ignored and you’ll end up with divergent quoting styles. Consider enforcing quotes through ESLint/Prettier instead and drop the custom key here.
Likewise, the [*.md]
section overrides insert_final_newline
to false
, contradicting the root section’s true
. Double-check that this is intentional; mixed behaviour across file types often surprises CI formatters.
🤖 Prompt for AI Agents
In the .editorconfig file around lines 9 to 13, remove the non-standard
'quote_type' key as it is not recognized by EditorConfig and may be ignored by
editors, leading to inconsistent quoting styles. Instead, enforce quote styles
using ESLint or Prettier configurations. Also, verify the '[*.md]' section does
not override 'insert_final_newline' to false if the root section sets it to
true, to avoid conflicting newline rules across file types; adjust or remove
this override if it is unintentional.
"extends": [ | ||
"eslint:recommended", | ||
"plugin:@typescript-eslint/recommended", | ||
"plugin:import-x/recommended", | ||
"plugin:import-x/typescript", | ||
"prettier" | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
"prettier"
still in extends
after removing .prettierrc
If Prettier is no longer part of the tool-chain, keeping the config in ESLint adds an unnecessary peer-dependency and runtime install step. Consider deleting the entry or restoring Prettier.
- "plugin:import-x/typescript",
- "prettier"
+ "plugin:import-x/typescript"
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
"extends": [ | |
"eslint:recommended", | |
"plugin:@typescript-eslint/recommended", | |
"plugin:import-x/recommended", | |
"plugin:import-x/typescript", | |
"prettier" | |
], | |
"extends": [ | |
"eslint:recommended", | |
"plugin:@typescript-eslint/recommended", | |
"plugin:import-x/recommended", | |
"plugin:import-x/typescript" | |
], |
🤖 Prompt for AI Agents
In .eslintrc.json around lines 6 to 12, the "prettier" entry remains in the
"extends" array despite removing the .prettierrc file. To fix this, either
remove the "prettier" entry from the "extends" array if Prettier is no longer
used, or restore the .prettierrc configuration file if Prettier should remain
part of the toolchain.
github: techwithanirudh | ||
buy_me_a_coffee: techwithanirudh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Line-ending mismatch violates repo style
YAMLlint warns about \r\n
. Convert to LF to align with .editorconfig
.
-github: techwithanirudh\r
-buy_me_a_coffee: techwithanirudh\r
+github: techwithanirudh
+buy_me_a_coffee: techwithanirudh
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
github: techwithanirudh | |
buy_me_a_coffee: techwithanirudh | |
github: techwithanirudh | |
buy_me_a_coffee: techwithanirudh |
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 1-1: wrong new line character: expected \n
(new-lines)
🤖 Prompt for AI Agents
In .github/FUNDING.yml at lines 1 to 2, the file uses Windows-style line endings
(\r\n) which violates the repository style that requires LF line endings.
Convert all line endings in this file from CRLF to LF to comply with the
.editorconfig settings and resolve the YAMLlint warning.
### Description | ||
|
||
<!-- Describe your changes in detail. What problem does this PR solve? --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Add a top-level H1 to satisfy markdownlint MD041
markdownlint flags the absence of a first-line heading. A minimal fix keeps the template valid without changing wording:
-### Description
+# Pull Request Template
+
+### Description
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
### Description | |
<!-- Describe your changes in detail. What problem does this PR solve? --> | |
# Pull Request Template | |
### Description | |
<!-- Describe your changes in detail. What problem does this PR solve? --> |
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🤖 Prompt for AI Agents
In .github/pull-request-template.md at lines 1 to 3, add a top-level H1 heading
as the very first line of the file to satisfy markdownlint rule MD041. This
heading should be minimal and can simply state something like "Pull Request
Template" to keep the template valid without altering the existing content.
"deploy": "bun run src/deploy-commands.ts", | ||
"typecheck": "tsc --noEmit", | ||
"check": "bun lint && bun typecheck && bun format:check && bun check:spelling", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
bun run src/deploy-commands.ts
script is dead code
src/deploy-commands.ts
was deleted in this PR, yet the deploy
npm script still references it – bun run
will exit with code 1.
Delete or replace the script.
- "deploy": "bun run src/deploy-commands.ts",
+ "deploy": "echo \"No longer applicable\"",
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
"deploy": "bun run src/deploy-commands.ts", | |
"typecheck": "tsc --noEmit", | |
"check": "bun lint && bun typecheck && bun format:check && bun check:spelling", | |
"deploy": "echo \"No longer applicable\"", | |
"typecheck": "tsc --noEmit", | |
"check": "bun lint && bun typecheck && bun format:check && bun check:spelling", |
🤖 Prompt for AI Agents
In package.json around lines 21 to 23, the "deploy" script references
src/deploy-commands.ts which was deleted in this PR, causing bun run to fail.
Remove the "deploy" script entirely or update it to point to a valid existing
file or command to prevent errors when running the deploy script.
src/utils/voice/helpers/ai.ts
Outdated
import { regularPrompt } from '@/lib/ai/prompts'; | ||
import { myProvider } from '@/lib/ai/providers'; | ||
import { generateText } from 'ai'; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unresolvable bare import "ai"
ES Lint cannot resolve ai
. If this comes from ai-sdk
you need either:
-import { generateText } from 'ai';
+import { generateText } from '@ai-sdk/core'; // or correct sub-path
or a path mapping in tsconfig.json
/ Bun’s import map.
Build will fail otherwise.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import { regularPrompt } from '@/lib/ai/prompts'; | |
import { myProvider } from '@/lib/ai/providers'; | |
import { generateText } from 'ai'; | |
import { regularPrompt } from '@/lib/ai/prompts'; | |
import { myProvider } from '@/lib/ai/providers'; | |
-import { generateText } from 'ai'; | |
+import { generateText } from '@ai-sdk/core'; // or correct sub-path |
🧰 Tools
🪛 ESLint
[error] 3-3: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
🤖 Prompt for AI Agents
In src/utils/voice/helpers/ai.ts at lines 1 to 4, the import statement for 'ai'
is unresolvable by ESLint and the build system. To fix this, replace the bare
import 'ai' with the correct module path or package name, such as 'ai-sdk' if
that is the intended source. Alternatively, configure a path mapping in
tsconfig.json or Bun's import map to resolve 'ai' to the correct location.
Ensure the import statement matches the actual installed package or configured
alias to prevent build failures.
const { text } = await generateText({ | ||
system: | ||
regularPrompt + | ||
'\n\nYou are talking to a person through a call, do not use markdown formatting, or emojis.', | ||
model: myProvider.languageModel('chat-model'), | ||
prompt, | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Prompt concatenation keeps growing – consider template literals
Minor readability tweak – use a template literal with ${regularPrompt}
instead of string concatenation.
- system:
- regularPrompt +
- '\n\nYou are talking to a person through a call, do not use markdown formatting, or emojis.',
+ system: `${regularPrompt}
+
+You are talking to a person through a call, do not use markdown formatting, or emojis.`,
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export async function getAIResponse(prompt: string): Promise<string> { | |
const { text } = await generateText({ | |
system: | |
regularPrompt + | |
'\n\nYou are talking to a person through a call, do not use markdown formatting, or emojis.', | |
model: myProvider.languageModel('chat-model'), | |
prompt, | |
}); | |
export async function getAIResponse(prompt: string): Promise<string> { | |
const { text } = await generateText({ | |
system: `${regularPrompt} | |
You are talking to a person through a call, do not use markdown formatting, or emojis.`, | |
model: myProvider.languageModel('chat-model'), | |
prompt, | |
}); |
🤖 Prompt for AI Agents
In src/utils/voice/helpers/ai.ts around lines 8 to 15, the prompt string is
concatenated using the plus operator, which reduces readability. Replace the
string concatenation with a template literal that embeds ${regularPrompt}
directly within backticks to improve clarity and maintainability.
/** | ||
* We will now play this to the audio player. By default, the audio player will not play until | ||
* at least one voice connection is subscribed to it, so it is fine to attach our resource to the | ||
* audio player this early. | ||
*/ | ||
player.play(resource); | ||
|
||
/** | ||
* Here we are using a helper function. It will resolve if the player enters the Playing | ||
* state within 5 seconds, otherwise it will reject with an error. | ||
*/ | ||
return entersState(player, AudioPlayerStatus.Playing, 5_000); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Voice helper kept, but self-bots cannot join voice channels
discord.js-selfbot-v13
purposefully strips voice support (Discord forbids self-bots connecting to VC). Any runtime call to playAudio
, joinVoiceChannel
, etc. will fail.
Options:
- Remove voice features altogether.
- Revert to a normal bot token /
discord.js
for voice. - Move voice logic to a separate service that uses a bot account.
Confirm the desired direction before shipping.
🤖 Prompt for AI Agents
In src/utils/voice/helpers/audio.ts around lines 24 to 36, the current voice
features rely on functionality that self-bots cannot use because Discord forbids
self-bots from joining voice channels. To fix this, decide on one approach:
either remove all voice-related code, switch to using a normal bot token with
discord.js for voice support, or isolate the voice logic into a separate service
running on a bot account. Implement the chosen approach consistently throughout
the codebase before shipping.
export async function speak({ text, model }: SpeakProps) { | ||
const response = await deepgram.speak.request( | ||
{ | ||
text, | ||
}, | ||
{ | ||
model: model, | ||
} | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Redundant object key shorthand
model: model
can be shorthand.
- model: model,
+ model,
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export async function speak({ text, model }: SpeakProps) { | |
const response = await deepgram.speak.request( | |
{ | |
text, | |
}, | |
{ | |
model: model, | |
} | |
); | |
export async function speak({ text, model }: SpeakProps) { | |
const response = await deepgram.speak.request( | |
{ | |
text, | |
}, | |
{ | |
model, | |
} | |
); |
🤖 Prompt for AI Agents
In src/utils/voice/helpers/deepgram.ts between lines 11 and 19, the object
passed to deepgram.speak.request uses redundant key-value syntax for the model
property. Replace `model: model` with the shorthand `model` to simplify the code
without changing functionality.
{ | ||
"compilerOptions": { | ||
// Environment setup & latest features | ||
"lib": ["ESNext"], | ||
"target": "ESNext", | ||
"module": "ESNext", | ||
"moduleDetection": "force", | ||
"jsx": "react-jsx", | ||
"allowJs": true, | ||
|
||
// Bundler mode | ||
"moduleResolution": "bundler", | ||
"allowImportingTsExtensions": true, | ||
"verbatimModuleSyntax": true, | ||
"noEmit": true, | ||
|
||
// Best practices | ||
"strict": true, | ||
"skipLibCheck": true, | ||
"noFallthroughCasesInSwitch": true, | ||
"noUncheckedIndexedAccess": true, | ||
|
||
// Some stricter flags (disabled by default) | ||
"noUnusedLocals": false, | ||
"noUnusedParameters": false, | ||
"noPropertyAccessFromIndexSignature": false, | ||
|
||
"paths": { | ||
"@/*": ["./src/*"] | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Avoid non-ASCII braces/whitespace – may break tooling
The PR description suggests this file was reformatted using full-width braces and spaces. Several editors, CLI tools, and CI linters choke on Unicode punctuation or indentation characters outside the ASCII range. It also makes diffs noisy.
Re-export the file with regular ASCII {}
and normal spaces/tabs to keep the configuration portable.
🤖 Prompt for AI Agents
In tsconfig.json lines 1 to 32, the file contains non-ASCII braces and
whitespace characters that can cause issues with editors, CLI tools, and CI
linters. Replace all full-width or Unicode braces and spaces with standard ASCII
curly braces and regular spaces or tabs to ensure compatibility and reduce noisy
diffs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (4)
src/events/message-create/utils/relevance.ts (1)
1-6
: Import changes look good and address previous feedback.The imports have been correctly updated:
- ✅
RequestHints
is now imported from@/types
(resolving the previous review comment)- ✅
Message
type updated to usediscord.js-selfbot-v13
(consistent with the selfbot migration)- ✅ Other imports remain appropriate for the function's purpose
src/utils/status.ts (1)
22-30
: Unsafe array indexing for activity type.The activity type mapping uses direct array indexing without bounds checking, which could cause runtime errors if
activity.type
is outside the expected range (0-6).- const activityType = [ - 'PLAYING', - 'STREAMING', - 'LISTENING', - 'WATCHING', - 'CUSTOM', - 'COMPETING', - 'HANG', - ][activity.type] as ActivityType; + const activityTypeMap: Record<number, ActivityType> = { + 0: 'PLAYING', + 1: 'STREAMING', + 2: 'LISTENING', + 3: 'WATCHING', + 4: 'CUSTOM', + 5: 'COMPETING', + 6: 'HANG', + }; + + const activityType = activityTypeMap[activity.type]; + if (!activityType) { + logger.error(`Invalid activity type: ${activity.type}`); + return; + }src/config.ts (2)
13-13
: Simplify speedFactor value.The multiplication
180 * 180
makes the actual value less clear. Consider using the computed value directly.- speedFactor: 180 * 180, + speedFactor: 32400,
18-41
: Use named constants for activity types.The numeric activity types (0, 2, 3, 5) are not self-documenting. Consider using named constants or an enum for better readability.
#!/bin/bash # Description: Check if ActivityType enum exists in discord.js-selfbot-v13 # Search for ActivityType enum definition in node_modules fd -t f "\.d\.ts$" node_modules/discord.js-selfbot-v13 --exec grep -l "enum ActivityType\|export.*ActivityType" {} \; | head -5 # Also check the actual usage in status.ts to understand the mapping cat src/utils/status.ts | grep -A 10 "activityType ="
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
src/config.ts
(1 hunks)src/events/message-create/utils/relevance.ts
(1 hunks)src/utils/status.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/events/message-create/utils/relevance.ts (4)
src/types/request.ts (1)
RequestHints
(3-12)src/lib/validators/probability.ts (2)
Probability
(17-17)probabilitySchema
(3-15)src/lib/ai/providers.ts (1)
myProvider
(21-33)src/lib/ai/prompts.ts (1)
systemPrompt
(62-76)
src/utils/status.ts (3)
src/index.ts (1)
client
(7-7)src/config.ts (2)
statuses
(16-16)activities
(18-41)src/types/activity.ts (1)
Activity
(1-5)
src/config.ts (1)
src/types/activity.ts (1)
Activity
(1-5)
🪛 ESLint
src/events/message-create/utils/relevance.ts
[error] 5-5: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
src/utils/status.ts
[error] 4-4: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
🔇 Additional comments (5)
src/events/message-create/utils/relevance.ts (1)
8-31
: Function implementation is clean and aligns with architectural changes.The
assessRelevance
function has been appropriately simplified:
- ✅ Removal of
memories
parameter aligns with the broader memory system elimination- ✅ Core logic remains intact with proper error handling
- ✅ System prompt configuration correctly uses
relevance-model
and passesrequestHints
- ✅ Default fallback provides reasonable probability (0.5) when processing fails
The implementation is consistent with the codebase migration from bot to selfbot architecture.
src/utils/status.ts (4)
8-14
: Well-implemented utility function with proper error handling.The
getRandomItem
function correctly handles edge cases and provides type safety.
32-50
: Well-implemented RichPresence with proper error handling.The external image fetching is properly handled with try-catch and optional chaining for safe property access.
60-66
: Good improvement to ensure initial status update completes.Making the function async and awaiting the initial update ensures proper initialization before scheduling periodic updates.
1-4
: All imports updated and dependency verified; remember Discord ToS risk
- Confirmed
discord.js-selfbot-v13
is declared in package.json (v^3.7.0).- No residual
import
statements fromdiscord.js
found in the codebase.⚠️ Selfbots violate Discord’s Terms of Service and may lead to account termination.
import { myProvider } from '@/lib/ai/providers'; | ||
import { probabilitySchema, type Probability } from '@/lib/validators'; | ||
import type { RequestHints } from '@/types'; | ||
import { generateObject, type ModelMessage } from 'ai'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify 'ai' package installation and module resolution.
ESLint is reporting that it cannot resolve the 'ai' module. Please ensure:
- The 'ai' package is installed in package.json dependencies
- ESLint module resolution is properly configured
- TypeScript path mappings are correct if using path aliases
🏁 Script executed:
#!/bin/bash
# Description: Check if 'ai' package is installed and verify import resolution
# Check if 'ai' package exists in package.json
echo "Checking package.json for 'ai' dependency:"
if [ -f "package.json" ]; then
jq '.dependencies.ai // .devDependencies.ai // "NOT_FOUND"' package.json
else
echo "package.json not found"
fi
echo -e "\nChecking if 'ai' package is installed in node_modules:"
if [ -d "node_modules/ai" ]; then
echo "✅ 'ai' package found in node_modules"
ls -la node_modules/ai/package.json 2>/dev/null || echo "No package.json in ai module"
else
echo "❌ 'ai' package not found in node_modules"
fi
echo -e "\nSearching for other files importing 'ai' module:"
rg "from ['\"]ai['\"]" --type ts --type js -A 1 -B 1
Length of output: 2438
Ensure the ‘ai’ package is installed and ESLint can resolve it
It looks like "ai": "^5.0.0-alpha.13"
is declared in package.json, but ESLint still flags all imports from ‘ai’ as unresolved (e.g. in src/events/message-create/utils/relevance.ts). To address this:
- Install or sync your dependencies (run
npm install
/yarn install
/pnpm install
) so thatnode_modules/ai
actually exists. - Verify your lockfile (
package-lock.json
/yarn.lock
) includes theai
entry. - Ensure ESLint’s module resolver is configured for Node packages (e.g. add or enable
import/resolver: { node: { extensions: [".js",".ts"] }}
in your .eslintrc).
Once the package is present and the resolver is set up, the “Unable to resolve path to module 'ai'” errors in files like:
- src/events/message-create/utils/relevance.ts
- src/utils/messages.ts
- src/utils/context.ts
- src/events/message-create/utils/respond.ts
- src/lib/ai/providers.ts
…will be cleared.
🧰 Tools
🪛 ESLint
[error] 5-5: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
🤖 Prompt for AI Agents
In src/events/message-create/utils/relevance.ts at line 5, ESLint flags imports
from 'ai' as unresolved because the package might not be properly installed or
ESLint is not configured to resolve it. To fix this, first run your package
manager's install command (npm install, yarn install, or pnpm install) to ensure
the 'ai' package is present in node_modules and reflected in your lockfile.
Then, update your ESLint configuration to include the Node resolver with
appropriate extensions by adding or enabling import/resolver: { node: {
extensions: [".js", ".ts"] } } in your .eslintrc file. This will allow ESLint to
correctly resolve the 'ai' module and remove the import errors.
const updateStatus = async (client: Client): Promise<void> => { | ||
if (!client.user) return; | ||
|
||
const status = getRandomItem(statuses) as PresenceStatusData; | ||
const activity = getRandomItem(activities) as Activity; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Consider safer type handling instead of assertions.
The type assertions on lines 19-20 could hide runtime errors if the arrays contain unexpected values.
- const status = getRandomItem(statuses) as PresenceStatusData;
- const activity = getRandomItem(activities) as Activity;
+ const status = getRandomItem(statuses);
+ const activity = getRandomItem(activities);
+
+ // Validate status is a valid PresenceStatusData
+ if (!['online', 'idle', 'dnd', 'invisible'].includes(status)) {
+ logger.error(`Invalid status: ${status}`);
+ return;
+ }
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/utils/status.ts around lines 16 to 20, the code uses type assertions to
cast values from arrays to specific types, which can mask runtime errors if the
arrays contain unexpected values. Replace these assertions with proper type
checks or validation logic to ensure the selected items conform to the expected
types before using them, thereby preventing potential runtime issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (2)
src/config.ts (2)
13-13
: Simplify speedFactor valueThe multiplication
180 * 180
makes the actual value less clear. Consider using the computed value directly.- speedFactor: 180 * 180, + speedFactor: 32400,
18-41
: Use ActivityType enum instead of raw numbersThe numeric activity types (0, 2, 3, 5) are not self-documenting. Consider using the ActivityType enum from discord.js-selfbot-v13 for better readability.
+import { ActivityType } from 'discord.js-selfbot-v13'; export const activities: Activity[] = [ { - type: 5, + type: ActivityType.Competing, name: 'painting', image: 'https://pbs.twimg.com/media/GrGH5PIaAAI7aLu?format=png&name=360x360', }, { - type: 2, + type: ActivityType.Listening, name: 'music', image: 'https://pbs.twimg.com/media/GtTOrD7bMAEfahJ?format=png&name=medium', }, { - type: 3, + type: ActivityType.Watching, name: 'tv', image: 'https://pbs.twimg.com/media/GuaO0GVbEAA3xHa?format=png&name=small', }, { - type: 0, + type: ActivityType.Playing, name: 'in the gym', image: 'https://pbs.twimg.com/media/GuvLw79XQAACrp3?format=png&name=900x900', }, ];
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
src/config.ts
(1 hunks)src/lib/ai/prompts.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/lib/ai/prompts.ts (2)
src/types/request.ts (1)
RequestHints
(3-12)src/config.ts (1)
initialMessages
(44-125)
src/config.ts (1)
src/types/activity.ts (1)
Activity
(1-5)
🔇 Additional comments (1)
src/config.ts (1)
44-125
: Review the appropriateness of initial messagesThe initial messages contain potentially problematic content:
- NSFW/inappropriate responses (e.g., "you're so sexy fr", "slayyyy btw this isn't reddit")
- Deliberately false information (e.g., "Grand Canyon in Maine")
- Potentially offensive language
While this aligns with the "troll" persona, consider whether this content is appropriate for your intended audience and use case.
src/lib/ai/prompts.ts
Outdated
${initialMessages.map((message) => `${message.content}`).join('\n')} | ||
`; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Consider preserving message roles in examples
The current implementation only shows message content without indicating which messages are from users vs assistant. This might reduce the effectiveness of the examples.
-${initialMessages.map((message) => `${message.content}`).join('\n')}
+${initialMessages.map((message) => `${message.role}: ${message.content}`).join('\n')}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
Reply Examples: | |
${initialMessages.map((message) => `${message.content}`).join('\n')} | |
`; | |
Reply Examples: | |
${initialMessages.map((message) => `${message.role}: ${message.content}`).join('\n')} | |
`; |
🤖 Prompt for AI Agents
In src/lib/ai/prompts.ts around lines 31 to 33, the reply examples only include
message content without showing the roles (user or assistant). Modify the
mapping to include each message's role along with its content, for example by
formatting each entry as "role: content". This will preserve the context of who
said what in the examples and improve their clarity.
src/lib/ai/prompts.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add explicit return for unmatched model types
The function implicitly returns undefined
when selectedChatModel
doesn't match 'chat-model' or 'relevance-model'. This could cause runtime errors.
export const systemPrompt = ({
selectedChatModel,
requestHints,
}: {
selectedChatModel: string;
requestHints: RequestHints;
}) => {
const requestPrompt = getRequestPromptFromHints(requestHints);
if (selectedChatModel === 'chat-model') {
return `${regularPrompt}\n\n${requestPrompt}\n\n${replyPrompt}`;
} else if (selectedChatModel === 'relevance-model') {
return `${regularPrompt}\n\n${requestPrompt}\n\n${artifactsPrompt}`;
}
+
+ throw new Error(`Unknown chat model: ${selectedChatModel}`);
};
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export const systemPrompt = ({ | |
selectedChatModel, | |
requestHints, | |
}: { | |
selectedChatModel: string; | |
requestHints: RequestHints; | |
}) => { | |
const requestPrompt = getRequestPromptFromHints(requestHints); | |
if (selectedChatModel === 'chat-model') { | |
return `${regularPrompt}\n\n${requestPrompt}\n\n${replyPrompt}`; | |
} else if (selectedChatModel === 'relevance-model') { | |
return `${regularPrompt}\n\n${requestPrompt}\n\n${artifactsPrompt}`; | |
} | |
}; | |
export const systemPrompt = ({ | |
selectedChatModel, | |
requestHints, | |
}: { | |
selectedChatModel: string; | |
requestHints: RequestHints; | |
}) => { | |
const requestPrompt = getRequestPromptFromHints(requestHints); | |
if (selectedChatModel === 'chat-model') { | |
return `${regularPrompt}\n\n${requestPrompt}\n\n${replyPrompt}`; | |
} else if (selectedChatModel === 'relevance-model') { | |
return `${regularPrompt}\n\n${requestPrompt}\n\n${artifactsPrompt}`; | |
} | |
throw new Error(`Unknown chat model: ${selectedChatModel}`); | |
}; |
🤖 Prompt for AI Agents
In src/lib/ai/prompts.ts around lines 71 to 85, the function systemPrompt
implicitly returns undefined if selectedChatModel is neither 'chat-model' nor
'relevance-model'. To fix this, add an explicit return statement at the end of
the function to handle unmatched model types, such as returning a default prompt
or throwing an error, ensuring the function always returns a string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
src/events/message-create/utils/respond.ts
(1 hunks)src/lib/ai/tools/join-server.ts
(1 hunks)src/lib/ai/tools/start-dm.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/events/message-create/utils/respond.ts (7)
src/types/message.ts (1)
MinimalContext
(14-33)src/types/request.ts (1)
RequestHints
(3-12)src/lib/ai/prompts.ts (1)
systemPrompt
(71-85)src/lib/ai/providers.ts (1)
myProvider
(21-33)src/lib/ai/tools/report.ts (1)
report
(6-34)src/lib/ai/tools/join-server.ts (1)
joinServer
(6-41)src/lib/ai/tools/start-dm.ts (1)
startDM
(6-82)
🪛 ESLint
src/lib/ai/tools/join-server.ts
[error] 3-3: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/events/message-create/utils/respond.ts
[error] 11-11: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
src/lib/ai/tools/start-dm.ts
[error] 3-3: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
🔇 Additional comments (4)
src/lib/ai/tools/start-dm.ts (1)
19-34
: Good fallback logic for user resolution.The implementation properly handles the case where a user ID fetch fails by falling back to username search, and correctly handles multiple users with the same username.
src/events/message-create/utils/respond.ts (3)
13-22
: Function simplification looks good.The removal of memories and options parameters aligns well with the overall simplification mentioned in the AI summary. The streamlined function signature makes the code more maintainable.
34-40
: Tool initialization pattern is consistent.The pattern of initializing tools that require message context (
report
,joinServer
,startDM
) while keeping others as direct references is well-implemented and consistent.
27-33
: All active tools are correctly implementedI’ve confirmed that each entry in
activeTools
—getWeather
,searchWeb
,report
,joinServer
, andstartDM
—is imported from its corresponding file and included as a key in thetools
object:
- Imports from:
src/lib/ai/tools/get-weather.ts
→getWeather
src/lib/ai/tools/search-web.ts
→searchWeb
src/lib/ai/tools/report.ts
→report
src/lib/ai/tools/join-server.ts
→joinServer
src/lib/ai/tools/start-dm.ts
→startDM
- All five keys match the strings in
activeTools
and are passed intogenerateText
.No missing or mismatched tool definitions were found.
import { joinServer } from '@/lib/ai/tools/join-server'; | ||
import { report } from '@/lib/ai/tools/report'; | ||
import { searchWeb } from '@/lib/ai/tools/search-web'; | ||
import { startDM } from '@/lib/ai/tools/start-dm'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Integration of ToS-violating selfbot tools.
The integration of joinServer
and startDM
tools introduces Discord Terms of Service violations into the AI response system. These tools enable automated user account actions that Discord explicitly prohibits.
Consider removing these tools or implementing equivalent functionality through Discord's official bot API to maintain compliance.
Also applies to: 31-32, 38-39
🤖 Prompt for AI Agents
In src/events/message-create/utils/respond.ts around lines 4 to 7, 31 to 32, and
38 to 39, the imports and usage of joinServer and startDM tools violate
Discord's Terms of Service by enabling prohibited automated user account
actions. Remove all references and calls to joinServer and startDM from the
code. If similar functionality is needed, reimplement it strictly using
Discord's official bot API methods to ensure compliance.
return { | ||
success: false, | ||
error: (e as Error)?.message, | ||
}; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Consider more specific error handling.
The generic error handling could provide more context for debugging tool execution failures.
} catch (e) {
+ logger.error({ error: e, messageId: msg.id, author: msg.author.username }, 'Failed to generate response');
return {
success: false,
- error: (e as Error)?.message,
+ error: (e as Error)?.message || 'An unexpected error occurred',
};
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
} catch (e) { | |
return { | |
success: false, | |
error: (e as Error)?.message, | |
}; | |
} | |
} catch (e) { | |
logger.error( | |
{ error: e, messageId: msg.id, author: msg.author.username }, | |
'Failed to generate response' | |
); | |
return { | |
success: false, | |
error: (e as Error)?.message || 'An unexpected error occurred', | |
}; | |
} |
🤖 Prompt for AI Agents
In src/events/message-create/utils/respond.ts around lines 46 to 51, the current
error handling is generic and only returns the error message. Improve this by
adding more specific error handling that captures additional context such as
error type, stack trace, or custom error properties. Modify the catch block to
extract and include these details in the returned error object to aid debugging
of tool execution failures.
src/lib/ai/tools/join-server.ts
Outdated
export const joinServer = ({ message }: { message: MinimalContext }) => | ||
tool({ | ||
description: 'Join a discord server.', | ||
parameters: z.object({ | ||
reason: z | ||
.string() | ||
.describe('The reason why you want to join the server.'), | ||
invite: z | ||
.string() | ||
.describe('The invite code of the server you want to join.'), | ||
}), | ||
execute: async ({ reason, invite }) => { | ||
const server = await message.client.fetchInvite(invite); | ||
|
||
logger.info( | ||
{ | ||
message: { | ||
author: message.author.username, | ||
}, | ||
server: server, | ||
reason: reason, | ||
invite: invite, | ||
}, | ||
'Joined a server' | ||
); | ||
|
||
await message.client.acceptInvite(invite); | ||
|
||
return { | ||
success: true, | ||
content: 'The server has been joined.', | ||
reason, | ||
invite, | ||
}; | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: This implementation violates Discord's Terms of Service.
Selfbots are explicitly prohibited by Discord's Terms of Service and can result in account termination. The acceptInvite
method from discord.js-selfbot-v13
automates user account interactions, which Discord considers a violation.
Consider implementing this functionality through Discord's official bot API instead, or remove this tool entirely to avoid ToS violations.
🤖 Prompt for AI Agents
In src/lib/ai/tools/join-server.ts lines 6 to 41, the current implementation
uses the acceptInvite method from discord.js-selfbot-v13, which violates
Discord's Terms of Service by automating user account actions. To fix this,
remove this tool entirely or refactor it to use Discord's official bot API for
joining servers, ensuring compliance with Discord's ToS and avoiding selfbot
usage.
.describe('The invite code of the server you want to join.'), | ||
}), | ||
execute: async ({ reason, invite }) => { | ||
const server = await message.client.fetchInvite(invite); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for Discord API calls.
The fetchInvite
and acceptInvite
calls should be wrapped in try-catch blocks to handle potential API errors gracefully.
execute: async ({ reason, invite }) => {
+ try {
const server = await message.client.fetchInvite(invite);
+ } catch (error) {
+ logger.error('Failed to fetch invite:', error);
+ return {
+ success: false,
+ error: 'Invalid or expired invite code',
+ };
+ }
logger.info(
{
message: {
author: message.author.username,
},
server: server,
reason: reason,
invite: invite,
},
'Joined a server'
);
+ try {
await message.client.acceptInvite(invite);
+ } catch (error) {
+ logger.error('Failed to join server:', error);
+ return {
+ success: false,
+ error: 'Failed to join the server',
+ };
+ }
return {
success: true,
content: 'The server has been joined.',
reason,
invite,
};
},
Also applies to: 32-32
🤖 Prompt for AI Agents
In src/lib/ai/tools/join-server.ts at lines 18 and 32, the calls to Discord API
methods fetchInvite and acceptInvite lack error handling. Wrap each of these
calls in try-catch blocks to catch any exceptions thrown by the API. In the
catch block, handle the error gracefully, such as logging the error or returning
a meaningful message, to prevent unhandled promise rejections and improve
robustness.
logger.info( | ||
{ | ||
message: { | ||
author: message.author.username, | ||
}, | ||
server: server, | ||
reason: reason, | ||
invite: invite, | ||
}, | ||
'Joined a server' | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Consider limiting server information in logs.
Logging the entire server object may expose sensitive information. Consider logging only essential fields like server name and ID.
logger.info(
{
message: {
author: message.author.username,
},
- server: server,
+ server: {
+ id: server.guild?.id,
+ name: server.guild?.name,
+ },
reason: reason,
invite: invite,
},
'Joined a server'
);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
logger.info( | |
{ | |
message: { | |
author: message.author.username, | |
}, | |
server: server, | |
reason: reason, | |
invite: invite, | |
}, | |
'Joined a server' | |
); | |
logger.info( | |
{ | |
message: { | |
author: message.author.username, | |
}, | |
server: { | |
id: server.guild?.id, | |
name: server.guild?.name, | |
}, | |
reason: reason, | |
invite: invite, | |
}, | |
'Joined a server' | |
); |
🤖 Prompt for AI Agents
In src/lib/ai/tools/join-server.ts between lines 20 and 30, the current logging
includes the entire server object, which may expose sensitive information.
Modify the log statement to include only essential server details such as the
server name and server ID instead of the full server object to limit sensitive
data exposure.
src/lib/ai/tools/start-dm.ts
Outdated
export const startDM = ({ message }: { message: MinimalContext }) => | ||
tool({ | ||
description: 'Start a DM with a user and send them a message.', | ||
parameters: z.object({ | ||
userId: z | ||
.string() | ||
.describe('The ID or username of the user you want to DM.'), | ||
content: z.string().describe('The message content to send to the user.'), | ||
}), | ||
execute: async ({ userId, content }) => { | ||
try { | ||
let user; | ||
|
||
try { | ||
user = await message.client.users.fetch(userId); | ||
} catch { | ||
const users = message.client.users.cache.filter( | ||
(u) => u.username === userId | ||
); | ||
if (users.size === 1) { | ||
user = users.first(); | ||
} else if (users.size > 1) { | ||
return { | ||
success: false, | ||
error: | ||
'Multiple users found with that username. Please use ID instead.', | ||
}; | ||
} | ||
} | ||
|
||
if (!user) { | ||
return { | ||
success: false, | ||
error: 'User not found', | ||
}; | ||
} | ||
|
||
try { | ||
const dm = await user.createDM(); | ||
await dm.send(content); | ||
} catch { | ||
await user.sendFriendRequest(); | ||
return { | ||
success: false, | ||
error: 'Could not DM user, sent friend request instead', | ||
}; | ||
} | ||
|
||
logger.info( | ||
{ | ||
message: { | ||
author: message.author.username, | ||
}, | ||
target: { | ||
id: user.id, | ||
username: user.username, | ||
}, | ||
content, | ||
}, | ||
'Started DM with user' | ||
); | ||
|
||
return { | ||
success: true, | ||
content: `Successfully sent DM to ${user.username}`, | ||
userId: user.id, | ||
messageContent: content, | ||
}; | ||
} catch (error) { | ||
logger.error('Failed to start DM:', error); | ||
return { | ||
success: false, | ||
error: 'Failed to send DM', | ||
}; | ||
} | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: This implementation violates Discord's Terms of Service.
Like the joinServer
tool, this selfbot functionality violates Discord's Terms of Service. Automated DM sending and friend request functionality using user accounts is explicitly prohibited and can result in account termination.
Additionally, automatically sending friend requests when DMs fail could be perceived as spam behavior, potentially leading to user reports and account penalties.
🤖 Prompt for AI Agents
In src/lib/ai/tools/start-dm.ts lines 6 to 82, the current implementation
automates sending DMs and friend requests using a user account, which violates
Discord's Terms of Service and risks account termination. To fix this, remove or
disable this tool entirely to prevent automated DM sending and friend requests.
If messaging functionality is needed, implement it using a Discord bot account
with proper permissions and user consent, ensuring compliance with Discord's
policies.
try { | ||
const dm = await user.createDM(); | ||
await dm.send(content); | ||
} catch { | ||
await user.sendFriendRequest(); | ||
return { | ||
success: false, | ||
error: 'Could not DM user, sent friend request instead', | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider rate limiting for friend requests.
Automatically sending friend requests when DMs fail could trigger Discord's spam detection. Consider implementing rate limiting or requiring explicit user consent before sending friend requests.
try {
const dm = await user.createDM();
await dm.send(content);
} catch {
- await user.sendFriendRequest();
return {
success: false,
- error: 'Could not DM user, sent friend request instead',
+ error: 'Could not DM user (privacy settings may prevent DMs)',
};
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
try { | |
const dm = await user.createDM(); | |
await dm.send(content); | |
} catch { | |
await user.sendFriendRequest(); | |
return { | |
success: false, | |
error: 'Could not DM user, sent friend request instead', | |
}; | |
} | |
try { | |
const dm = await user.createDM(); | |
await dm.send(content); | |
} catch { | |
return { | |
success: false, | |
error: 'Could not DM user (privacy settings may prevent DMs)', | |
}; | |
} |
🤖 Prompt for AI Agents
In src/lib/ai/tools/start-dm.ts between lines 43 and 52, the code sends a friend
request automatically if sending a DM fails, which risks triggering Discord's
spam detection. Modify the code to implement rate limiting for sending friend
requests, such as tracking the timestamp of the last friend request sent and
only allowing a new one after a cooldown period. Alternatively, require explicit
user consent before sending friend requests instead of sending them
automatically.
} catch (error) { | ||
logger.error('Failed to start DM:', error); | ||
return { | ||
success: false, | ||
error: 'Failed to send DM', | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Improve error logging specificity.
The generic error handling could benefit from more specific error information to aid debugging.
} catch (error) {
- logger.error('Failed to start DM:', error);
+ logger.error({ error, userId, targetUser: user?.username }, 'Failed to start DM');
return {
success: false,
- error: 'Failed to send DM',
+ error: `Failed to send DM: ${error instanceof Error ? error.message : 'Unknown error'}`,
};
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
} catch (error) { | |
logger.error('Failed to start DM:', error); | |
return { | |
success: false, | |
error: 'Failed to send DM', | |
}; | |
} | |
} catch (error) { | |
logger.error({ error, userId, targetUser: user?.username }, 'Failed to start DM'); | |
return { | |
success: false, | |
error: `Failed to send DM: ${error instanceof Error ? error.message : 'Unknown error'}`, | |
}; | |
} |
🤖 Prompt for AI Agents
In src/lib/ai/tools/start-dm.ts around lines 74 to 80, the error logging is too
generic and does not provide specific details about the failure. Update the
catch block to log more specific error information by including error properties
such as error.message or error.stack if available. This will improve debugging
by giving clearer insight into what caused the failure when starting the DM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
package.json (2)
35-48
: Unresolved peer-dependency conflict remains
@discordjs/[email protected]
hard-pinsdiscord.js@^14
but the project now depends on[email protected]
. This mismatch will still breaknpm|bun install
and runtime.Please either drop
@discordjs/voice
(or related code) or switch back to a compatiblediscord.js@14
build.
21-21
:deploy
script still points at removed file
src/deploy-commands.ts
was deleted yet the script is unchanged, sobun run deploy
exits with code 1.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (2)
VECTOR.md
(1 hunks)package.json
(2 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
package.json
[warning] 1-1: Prettier formatting warning: code style issues found. Run 'prettier --write' to fix.
VECTOR.md
[error] 4-4: cspell: Unknown word 'metdata'. Suggested fix: 'metadata'.
[error] 11-11: cspell: Unknown word 'aswell'. Suggested fix: 'as well'.
[error] 16-16: cspell: Unknown word 'rerankinig'.
🪛 LanguageTool
VECTOR.md
[grammar] ~3-~3: Use hyphens correctly
Context: ...g: 1. As we use the AI SDK, we will use OpenAI compatible models for embedding, like em...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~3-~3: Insert the missing word
Context: ...bedding large (use models, embedding in models.ts), same with searching for data. 2. We use...
(QB_NEW_EN_OTHER_ERROR_IDS_32)
[grammar] ~4-~4: Ensure spelling is correct
Context: ...-index#bring-your-own-vectors), include metdata like timestamp, user, server, channel, ...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~4-~4: Use a comma after introductory words or phrases
Context: ...mp, user, server, channel, etc. So when searching we can limit the search to a specific s...
(QB_NEW_EN_OTHER_ERROR_IDS_19)
[grammar] ~5-~5: Use a comma after introductory words or phrases
Context: ...-filter) 3. We do NOT need to chunk the data as discord messages are already short a...
(QB_NEW_EN_OTHER_ERROR_IDS_19)
[grammar] ~6-~6: There might be a mistake here.
Context: ...we should remove the embedding from the index, or update it. (https://docs.pinecone.i...
(QB_NEW_EN_OTHER)
[grammar] ~6-~6: Make sure to use plural and singular nouns correctly
Context: ...e-chunks). Have a way to easily connect message and embedding id. 5. After all this we ...
(QB_NEW_EN_OTHER_ERROR_IDS_10)
[grammar] ~6-~6: There might be a mistake here.
Context: ...to easily connect message and embedding id. 5. After all this we can upsert the emb...
(QB_NEW_EN_OTHER)
[grammar] ~11-~11: Use a comma after introductory words or phrases
Context: ...g-your-own-vectors) # Searches - When searching have a sophisticated algo (bob), check ...
(QB_NEW_EN_OTHER_ERROR_IDS_19)
[grammar] ~11-~11: There might be a mistake here.
Context: ...s - When searching have a sophisticated algo (bob), check through server, recent mes...
(QB_NEW_EN_OTHER)
[grammar] ~11-~11: Use articles correctly
Context: ...sophisticated algo (bob), check through server, recent messages, and a lot of context a...
(QB_NEW_EN_OTHER_ERROR_IDS_11)
[grammar] ~11-~11: There might be a problem here.
Context: ...h server, recent messages, and a lot of context aswell so we get the data. w/metadata timefram...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~15-~15: There might be a mistake here.
Context: ...-semantic-search) # TODO Learn about namespaces Learn about rerankinig (https://docs.pin...
(QB_NEW_EN_OTHER)
[grammar] ~17-~17: There might be a mistake here.
Context: ...d/quickstart#6-rerank-results) Look at bob code (https://docs.pinecone.io/guides/g...
(QB_NEW_EN_OTHER)
[grammar] ~18-~18: Use articles correctly
Context: ...d/quickstart#7-improve-results) Look at AI SDK pinecone example so we can implemen...
(QB_NEW_EN_OTHER_ERROR_IDS_11)
[grammar] ~18-~18: Use a period to end declarative sentences
Context: ...DK pinecone example so we can implement it
(QB_NEW_EN_OTHER_ERROR_IDS_25)
🪛 markdownlint-cli2 (0.17.2)
VECTOR.md
1-1: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
3-3: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
4-4: Bare URL used
(MD034, no-bare-urls)
4-4: Bare URL used
(MD034, no-bare-urls)
6-6: Bare URL used
(MD034, no-bare-urls)
6-6: Bare URL used
(MD034, no-bare-urls)
7-7: Bare URL used
(MD034, no-bare-urls)
7-7: Bare URL used
(MD034, no-bare-urls)
9-9: Multiple consecutive blank lines
Expected: 1; Actual: 2
(MD012, no-multiple-blanks)
10-10: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
10-10: Multiple top-level headings in the same document
(MD025, single-title, single-h1)
11-11: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
11-11: Bare URL used
(MD034, no-bare-urls)
13-13: Multiple consecutive blank lines
Expected: 1; Actual: 2
(MD012, no-multiple-blanks)
14-14: Trailing spaces
Expected: 0 or 2; Actual: 1
(MD009, no-trailing-spaces)
14-14: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
14-14: Multiple top-level headings in the same document
(MD025, single-title, single-h1)
16-16: Bare URL used
(MD034, no-bare-urls)
17-17: Bare URL used
(MD034, no-bare-urls)
18-18: Files should end with a single newline character
(MD047, single-trailing-newline)
🔇 Additional comments (1)
package.json (1)
39-39
: Pinecone client dependency addition looks good
@pinecone-database/pinecone@^6.1.2
aligns with the new VECTOR.md design; no issues spotted.
VECTOR.md
Outdated
# Vector | ||
Let's use Pinecone for the following: | ||
1. As we use the AI SDK, we will use OpenAI compatible models for embedding, like embedding large (use models, embedding in models.ts), same with searching for data. | ||
2. We use a dense index in Pinecone for semantic search, matching the output of modern embedding models and the bot's use case. (https://docs.pinecone.io/guides/index-data/create-an-index#bring-your-own-vectors), include metdata like timestamp, user, server, channel, etc. So when searching we can limit the search to a specific server, channel, etc. (https://docs.pinecone.io/guides/search/filter-by-metadata#search-with-a-metadata-filter) | ||
3. We do NOT need to chunk the data as discord messages are already short and concise. | ||
4. When a message is deleted or edited, we should remove the embedding from the index, or update it. (https://docs.pinecone.io/guides/index-data/data-modeling#delete-chunks, https://docs.pinecone.io/guides/index-data/data-modeling#update-chunks). Have a way to easily connect message and embedding id. | ||
5. After all this we can upsert the embeddings to the index. (https://docs.pinecone.io/guides/index-data/upsert-data#upsert-dense-vectors) (https://docs.pinecone.io/guides/index-data/indexing-overview#bring-your-own-vectors) | ||
|
||
|
||
# Searches | ||
- When searching have a sophisticated algo (bob), check through server, recent messages, and a lot of context aswell so we get the data. w/metadata timeframes, users etc. (https://docs.pinecone.io/guides/get-started/quickstart#5-semantic-search) | ||
|
||
|
||
# TODO | ||
Learn about namespaces | ||
Learn about rerankinig (https://docs.pinecone.io/guides/get-started/quickstart#6-rerank-results) | ||
Look at bob code (https://docs.pinecone.io/guides/get-started/quickstart#7-improve-results) | ||
Look at AI SDK pinecone example so we can implement it No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix markdown & spelling errors to unblock CI
CI fails on markdown-lint and cspell. Apply the following minimal patch; then run prettier
/ markdownlint
to satisfy linters.
-# Vector
-Let's use Pinecone for the following:
-1. As we use the AI SDK, we will use OpenAI compatible models for embedding, like embedding large (use models, embedding in models.ts), same with searching for data.
-2. We use a dense index in Pinecone for semantic search, matching the output of modern embedding models and the bot's use case. (https://docs.pinecone.io/guides/index-data/create-an-index#bring-your-own-vectors), include metdata like timestamp, user, server, channel, etc. So when searching we can limit the search to a specific server, channel, etc. (https://docs.pinecone.io/guides/search/filter-by-metadata#search-with-a-metadata-filter)
-3. We do NOT need to chunk the data as discord messages are already short and concise.
-4. When a message is deleted or edited, we should remove the embedding from the index, or update it. (https://docs.pinecone.io/guides/index-data/data-modeling#delete-chunks, https://docs.pinecone.io/guides/index-data/data-modeling#update-chunks). Have a way to easily connect message and embedding id.
-5. After all this we can upsert the embeddings to the index. (https://docs.pinecone.io/guides/index-data/upsert-data#upsert-dense-vectors) (https://docs.pinecone.io/guides/index-data/indexing-overview#bring-your-own-vectors)
-
-# Searches
-- When searching have a sophisticated algo (bob), check through server, recent messages, and a lot of context aswell so we get the data. w/metadata timeframes, users etc. (https://docs.pinecone.io/guides/get-started/quickstart#5-semantic-search)
-
-# TODO
-Learn about namespaces
-Learn about rerankinig (https://docs.pinecone.io/guides/get-started/quickstart#6-rerank-results)
-Look at bob code (https://docs.pinecone.io/guides/get-started/quickstart#7-improve-results)
-Look at AI SDK pinecone example so we can implement it
+# Vector
+
+We will use **Pinecone** for the following:
+
+1. Use OpenAI-compatible embedding models (see `models.ts`) with the AI SDK for both embedding and search.
+2. Create a **dense** index in Pinecone (https://docs.pinecone.io/guides/index-data/create-an-index#bring-your-own-vectors) and include metadata (timestamp, user, server, channel, etc.) so searches can be filtered (https://docs.pinecone.io/guides/search/filter-by-metadata#search-with-a-metadata-filter).
+3. No chunking required because Discord messages are short.
+4. When a message is deleted or edited, remove or update its embedding (https://docs.pinecone.io/guides/index-data/data-modeling#delete-chunks). Maintain a mapping between Discord message IDs and embedding IDs.
+5. Upsert embeddings via Pinecone’s upsert endpoint (https://docs.pinecone.io/guides/index-data/upsert-data#upsert-dense-vectors).
+
+# Searches
+
+- Implement a sophisticated search algorithm that considers server context, recent messages, and metadata filters such as timeframe or user (https://docs.pinecone.io/guides/get-started/quickstart#5-semantic-search).
+
+# TODO
+
+* Learn about namespaces
+* Learn about reranking (https://docs.pinecone.io/guides/get-started/quickstart#6-rerank-results)
+* Review reference code (https://docs.pinecone.io/guides/get-started/quickstart#7-improve-results)
+* Check AI SDK + Pinecone example for implementation guidance.
+
Key fixes:
• Spelling: metadata
, as well
, reranking
.
• Blank lines around headings/lists.
• Trailing newline.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
# Vector | |
Let's use Pinecone for the following: | |
1. As we use the AI SDK, we will use OpenAI compatible models for embedding, like embedding large (use models, embedding in models.ts), same with searching for data. | |
2. We use a dense index in Pinecone for semantic search, matching the output of modern embedding models and the bot's use case. (https://docs.pinecone.io/guides/index-data/create-an-index#bring-your-own-vectors), include metdata like timestamp, user, server, channel, etc. So when searching we can limit the search to a specific server, channel, etc. (https://docs.pinecone.io/guides/search/filter-by-metadata#search-with-a-metadata-filter) | |
3. We do NOT need to chunk the data as discord messages are already short and concise. | |
4. When a message is deleted or edited, we should remove the embedding from the index, or update it. (https://docs.pinecone.io/guides/index-data/data-modeling#delete-chunks, https://docs.pinecone.io/guides/index-data/data-modeling#update-chunks). Have a way to easily connect message and embedding id. | |
5. After all this we can upsert the embeddings to the index. (https://docs.pinecone.io/guides/index-data/upsert-data#upsert-dense-vectors) (https://docs.pinecone.io/guides/index-data/indexing-overview#bring-your-own-vectors) | |
# Searches | |
- When searching have a sophisticated algo (bob), check through server, recent messages, and a lot of context aswell so we get the data. w/metadata timeframes, users etc. (https://docs.pinecone.io/guides/get-started/quickstart#5-semantic-search) | |
# TODO | |
Learn about namespaces | |
Learn about rerankinig (https://docs.pinecone.io/guides/get-started/quickstart#6-rerank-results) | |
Look at bob code (https://docs.pinecone.io/guides/get-started/quickstart#7-improve-results) | |
Look at AI SDK pinecone example so we can implement it | |
# Vector | |
We will use **Pinecone** for the following: | |
1. Use OpenAI-compatible embedding models (see `models.ts`) with the AI SDK for both embedding and search. | |
2. Create a **dense** index in Pinecone (https://docs.pinecone.io/guides/index-data/create-an-index#bring-your-own-vectors) and include metadata (timestamp, user, server, channel, etc.) so searches can be filtered (https://docs.pinecone.io/guides/search/filter-by-metadata#search-with-a-metadata-filter). | |
3. No chunking required because Discord messages are short. | |
4. When a message is deleted or edited, remove or update its embedding (https://docs.pinecone.io/guides/index-data/data-modeling#delete-chunks). Maintain a mapping between Discord message IDs and embedding IDs. | |
5. Upsert embeddings via Pinecone’s upsert endpoint (https://docs.pinecone.io/guides/index-data/upsert-data#upsert-dense-vectors). | |
# Searches | |
- Implement a sophisticated search algorithm that considers server context, recent messages, and metadata filters such as timeframe or user (https://docs.pinecone.io/guides/get-started/quickstart#5-semantic-search). | |
# TODO | |
* Learn about namespaces | |
* Learn about reranking (https://docs.pinecone.io/guides/get-started/quickstart#6-rerank-results) | |
* Review reference code (https://docs.pinecone.io/guides/get-started/quickstart#7-improve-results) | |
* Check AI SDK + Pinecone example for implementation guidance. |
🧰 Tools
🪛 LanguageTool
[grammar] ~3-~3: Use hyphens correctly
Context: ...g: 1. As we use the AI SDK, we will use OpenAI compatible models for embedding, like em...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~3-~3: Insert the missing word
Context: ...bedding large (use models, embedding in models.ts), same with searching for data. 2. We use...
(QB_NEW_EN_OTHER_ERROR_IDS_32)
[grammar] ~4-~4: Ensure spelling is correct
Context: ...-index#bring-your-own-vectors), include metdata like timestamp, user, server, channel, ...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~4-~4: Use a comma after introductory words or phrases
Context: ...mp, user, server, channel, etc. So when searching we can limit the search to a specific s...
(QB_NEW_EN_OTHER_ERROR_IDS_19)
[grammar] ~5-~5: Use a comma after introductory words or phrases
Context: ...-filter) 3. We do NOT need to chunk the data as discord messages are already short a...
(QB_NEW_EN_OTHER_ERROR_IDS_19)
[grammar] ~6-~6: There might be a mistake here.
Context: ...we should remove the embedding from the index, or update it. (https://docs.pinecone.i...
(QB_NEW_EN_OTHER)
[grammar] ~6-~6: Make sure to use plural and singular nouns correctly
Context: ...e-chunks). Have a way to easily connect message and embedding id. 5. After all this we ...
(QB_NEW_EN_OTHER_ERROR_IDS_10)
[grammar] ~6-~6: There might be a mistake here.
Context: ...to easily connect message and embedding id. 5. After all this we can upsert the emb...
(QB_NEW_EN_OTHER)
[grammar] ~11-~11: Use a comma after introductory words or phrases
Context: ...g-your-own-vectors) # Searches - When searching have a sophisticated algo (bob), check ...
(QB_NEW_EN_OTHER_ERROR_IDS_19)
[grammar] ~11-~11: There might be a mistake here.
Context: ...s - When searching have a sophisticated algo (bob), check through server, recent mes...
(QB_NEW_EN_OTHER)
[grammar] ~11-~11: Use articles correctly
Context: ...sophisticated algo (bob), check through server, recent messages, and a lot of context a...
(QB_NEW_EN_OTHER_ERROR_IDS_11)
[grammar] ~11-~11: There might be a problem here.
Context: ...h server, recent messages, and a lot of context aswell so we get the data. w/metadata timefram...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~15-~15: There might be a mistake here.
Context: ...-semantic-search) # TODO Learn about namespaces Learn about rerankinig (https://docs.pin...
(QB_NEW_EN_OTHER)
[grammar] ~17-~17: There might be a mistake here.
Context: ...d/quickstart#6-rerank-results) Look at bob code (https://docs.pinecone.io/guides/g...
(QB_NEW_EN_OTHER)
[grammar] ~18-~18: Use articles correctly
Context: ...d/quickstart#7-improve-results) Look at AI SDK pinecone example so we can implemen...
(QB_NEW_EN_OTHER_ERROR_IDS_11)
[grammar] ~18-~18: Use a period to end declarative sentences
Context: ...DK pinecone example so we can implement it
(QB_NEW_EN_OTHER_ERROR_IDS_25)
🪛 markdownlint-cli2 (0.17.2)
1-1: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
3-3: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
4-4: Bare URL used
(MD034, no-bare-urls)
4-4: Bare URL used
(MD034, no-bare-urls)
6-6: Bare URL used
(MD034, no-bare-urls)
6-6: Bare URL used
(MD034, no-bare-urls)
7-7: Bare URL used
(MD034, no-bare-urls)
7-7: Bare URL used
(MD034, no-bare-urls)
9-9: Multiple consecutive blank lines
Expected: 1; Actual: 2
(MD012, no-multiple-blanks)
10-10: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
10-10: Multiple top-level headings in the same document
(MD025, single-title, single-h1)
11-11: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
11-11: Bare URL used
(MD034, no-bare-urls)
13-13: Multiple consecutive blank lines
Expected: 1; Actual: 2
(MD012, no-multiple-blanks)
14-14: Trailing spaces
Expected: 0 or 2; Actual: 1
(MD009, no-trailing-spaces)
14-14: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
14-14: Multiple top-level headings in the same document
(MD025, single-title, single-h1)
16-16: Bare URL used
(MD034, no-bare-urls)
17-17: Bare URL used
(MD034, no-bare-urls)
18-18: Files should end with a single newline character
(MD047, single-trailing-newline)
🪛 GitHub Actions: CI
[error] 4-4: cspell: Unknown word 'metdata'. Suggested fix: 'metadata'.
[error] 11-11: cspell: Unknown word 'aswell'. Suggested fix: 'as well'.
[error] 16-16: cspell: Unknown word 'rerankinig'.
🤖 Prompt for AI Agents
In VECTOR.md lines 1 to 18, fix markdown and spelling errors to unblock CI by
correcting misspelled words such as "metadata", "as well", and "reranking". Add
blank lines before and after headings and lists to comply with markdown-lint
rules. Ensure the file ends with a trailing newline. After these changes, run
prettier and markdownlint to satisfy all linters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🔭 Outside diff range comments (1)
README.md (1)
1-80
: Fix formatting issues to unblock CI.Multiple formatting issues are causing CI failures. Please run
prettier --write README.md
to resolve these formatting inconsistencies.#!/bin/bash # Run prettier to fix formatting issues prettier --write README.md
♻️ Duplicate comments (2)
README.md (1)
29-29
: Update documentation to reflect selfbot architecture.The instructions still refer to creating a "Discord Bot" but the codebase has migrated to a selfbot model using
discord.js-selfbot-v13
. This creates confusion about the actual setup process.-To clone and run this application, first you need to create a [Discord Bot](https://www.androidpolice.com/how-to-make-discord-bot/). Afterwards, you will need [Git][git] and [Bun][bun] installed on your computer. +To clone and run this application, you will need [Git][git] and [Bun][bun] installed on your computer. Note: This is a selfbot implementation that uses your personal Discord account.VECTOR.md (1)
1-18
: Fix markdown & spelling errors to unblock CI.The same formatting and spelling issues identified in previous reviews persist, including misspelled words like "metdata", "aswell", and "rerankinig", plus markdown formatting violations.
Please apply the previously suggested fixes to resolve CI failures and improve document readability.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
README.md
(1 hunks)TODO.md
(1 hunks)VECTOR.md
(1 hunks)src/env.ts
(1 hunks)src/lib/ai/pinecone.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/lib/ai/pinecone.ts (1)
src/env.ts (1)
env
(4-56)
🪛 LanguageTool
TODO.md
[grammar] ~4-~4: Use comma(s) to set off direct address
Context: ...t (Done)
The Discord Agent Isolation...
(QB_NEW_EN_OTHER_ERROR_IDS_18)
[grammar] ~4-~4: Use correct spacing
Context: ...nal goal) - @grok (gork) / @zenix is it true?
The Discord Agent Isolation for each ser...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~6-~6: Use proper capitalization
Context: ...d Agent Isolation for each server, full RBAC
Switch to ElevenLabs instead of deepgram...
(QB_NEW_EN_OTHER_ERROR_IDS_6)
[grammar] ~7-~7: Use comma(s) to set off direct address
Context: ...itch to ElevenLabs instead of deepgram voice as it's more realistic.
Separate Dee...
(QB_NEW_EN_OTHER_ERROR_IDS_18)
[grammar] ~7-~7: Use correct spacing
Context: ... instead of deepgram voice as it's more realistic.
Separate Deepgram code into it's files
...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~9-~9: There might be a problem here.
Context: ...alistic.
Separate Deepgram code into it's files
Implement Conversation history for Voice...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~10-~10: There might be a mistake here.
Context: ...istory for Voice Chat, previous message memory + chat history.
Add Commit Lint to enfo...
(QB_NEW_EN_OTHER)
[grammar] ~10-~10: Use correct spacing
Context: ...ce Chat, previous message memory + chat history.
Add Commit Lint to enforce strict commit me...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~11-~11: Use correct spacing
Context: ...ce strict commit messages, and add lint pipelines.
Allow People to Customize Zenix's Speed, and ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~12-~12: Use commas correctly
Context: ...es.
Allow People to Customize Zenix's Speed, and other settings in a /config command ...
(QB_NEW_EN_OTHER_ERROR_IDS_33)
[grammar] ~12-~12: Use hyphens correctly
Context: ...and other settings in a /config command (per-server).
Refactor the channels command to be mo...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~13-~13: There might be a problem here.
Context: ...).
Refactor the channels command to be more easy to use, with deny and allow lists.
D...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~13-~13: Use correct spacing
Context: ...e more easy to use, with deny and allow lists.
Detect when the user sent an unfinished ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~15-~15: There might be a mistake here.
Context: ...y complete the response before replying fully, wait 1-2 seconds (for one user). This a...
(QB_NEW_EN_OTHER)
[grammar] ~15-~15: There might be a mistake here.
Context: ...t 1-2 seconds (for one user). This adds deduping
If a user interrupts it's replying, it w...
(QB_NEW_EN_OTHER)
[grammar] ~17-~17: There might be a problem here.
Context: ...s adds deduping
If a user interrupts it's replying, it will pause the current repl...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~17-~17: Use correct spacing
Context: ...t reply and reply to the other one with context.
Have a small dashboard UI to modify the ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~19-~19: There might be a problem here.
Context: ...Have a small dashboard UI to modify the bots settings
Add a slash chat command to chat with th...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~20-~20: Use correct spacing
Context: ...ash chat command to chat with the AI on servers.
Figure out the issue if you join and close str...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~21-~21: Use articles correctly
Context: ...ure out the issue if you join and close stream multiple DeepGram things are kept
Wh...
(QB_NEW_EN_OTHER_ERROR_IDS_11)
[grammar] ~21-~21: There might be a mistake here.
Context: ...ose stream multiple DeepGram things are kept
When the user is typing increase the res...
(QB_NEW_EN_OTHER)
[grammar] ~23-~23: Use a comma after introductory words or phrases
Context: ...ram things are kept
When the user is typing increase the response speed by 0.5x. Al...
(QB_NEW_EN_OTHER_ERROR_IDS_19)
[grammar] ~23-~23: Use correct spacing
Context: ...ferent method for responding like a set WPM.
Add CI/CD testing so pushing things to p...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~25-~25: Use modal and auxiliary verbs correctly
Context: ...testing so pushing things to production don't break stuff.
Add context to when ...
(QB_NEW_EN_OTHER_ERROR_IDS_24)
[grammar] ~25-~25: Use correct spacing
Context: ...ushing things to production don't break stuff.
Add context to when the bot is triggered...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~27-~27: Use correct spacing
Context: ...due to a ping, a message, or some other interaction.
Switch from Mem0 (free, limited plan) to...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~29-~29: Use correct spacing
Context: ...ous messages, and maintain context over time.
Look into CrewAI or build your own custo...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~31-~31: Use correct spacing
Context: ...ntegrated with both voice chat and text messages.
Zenix should have unified memory per use...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~33-~33: Use correct spacing
Context: ...rson no matter where they interact with it.
Fix commands (broken on autobotting)
Clean...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~34-~34: There might be a mistake here.
Context: ...eract with it.
Fix commands (broken on autobotting)
Cleanup memory part later
(QB_NEW_EN_OTHER)
[grammar] ~35-~35: Use a period to end declarative sentences
Context: ...en on autobotting)
Cleanup memory part later
(QB_NEW_EN_OTHER_ERROR_IDS_25)
README.md
[grammar] ~3-~3: Use correct spacing
Context: ...">AI Discord Bot
📋 Table of Contents
- 🤖 Introduction
- 🚀 ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~9-~9: Use correct spacing
Context: ...tarted)
4. 🧠 Memory
4. 📝 License
🤖 Introduction
A human-like bot ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~11-~11: Use correct spacing
Context: ...icense)
🤖 Introduction
A human-like bot that is almost indistin...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~13-~13: Use correct spacing
Context: ...is almost indistinguishable from a real person.
🚀 Tech Stack
This project was de...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~15-~15: Use correct spacing
Context: ...son.
🚀 Tech Stack
This project was developed with the foll...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~17-~17: There might be a mistake here.
Context: ...roject was developed with the following technologies:
- [Vercel AI SDK][ai-sdk]
- [Exa AI][exa]...
(QB_NEW_EN_OTHER)
[grammar] ~25-~25: Use correct spacing
Context: ...]
- [Bun][bun]
- [ESLint][eslint]
- [Prettier][prettier]
📚 Getting Started
To clone and r...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~27-~27: Use correct spacing
Context: ...## 📚 Getting Started
To clone and run this application, first...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[locale-violation] ~29-~29: In American English, ‘afterward’ is the preferred variant. ‘Afterwards’ is more commonly used in British English and other dialects.
Context: ...idpolice.com/how-to-make-discord-bot/). Afterwards, you will need [Git][git] and [Bun][bun...
(AFTERWARDS_US)
[grammar] ~29-~29: Use correct spacing
Context: ...][git] and [Bun][bun] installed on your computer.
From your command line:
# Cl...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~31-~31: There might be a mistake here.
Context: ... on your computer.
From your command line:
```bash
# Clone this repository
$ git clone https://github.com/techwithanirudh/discord-ai-bot.git
# Install dependencies
$ bun install
Next, copy the .env.example fil...
(QB_NEW_EN_OTHER)
[grammar] ~41-~41: Use correct spacing
Context: ...me it to .env, and add your environment variables.
Great! Now you just need to start the developm...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~42-~42: Use correct spacing
Context: ... you just need to start the development server.
# Start server
$ bun run dev
🧠 Memory
This bot uses Pinecone ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~49-~49: Use correct spacing
Context: ... run dev
## <a name="memory">🧠 Memory</a>
This bot uses Pinecone to store memory. ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~51-~51: Use correct spacing
Context: ...t variable to the name of your Pinecone index.
Set the `PINECONE_API_KEY` environment v...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~53-~53: Use correct spacing
Context: ...vironment variable to your Pinecone API key.
Then, create a Pinecone index and set th...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~55-~55: Use correct spacing
Context: ...t variable to the name of your Pinecone index.
Spec:
- Pinecone index should be dense
...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~58-~58: There might be a mistake here.
Context: ...x.
Spec:
- Pinecone index should be dense
- Dimension: 1536
- Metric: dotproduct
-...
(QB_NEW_EN_OTHER)
---
[grammar] ~60-~60: There might be a problem here.
Context: ...x should be dense
- Dimension: 1536
- Metric: dotproduct
- Spec: aws, us-east-1
- Namespace: `...
(QB_NEW_EN_MERGED_MATCH)
---
[grammar] ~62-~62: Use correct spacing
Context: ...: dotproduct
- Spec: aws, us-east-1
- Namespace: `default`
## <a name="license">📝 License</a>
This project is under ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~64-~64: Use correct spacing
Context: ...e: `default`
## <a name="license">📝 License</a>
This project is under the MIT license. S...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~66-~66: Use correct spacing
Context: ...license. See the [LICENSE](LICENSE) for details.
> Credit to Fellipe Utaka for the [Discord...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~68-~68: Use correct spacing
Context: ...t to Fellipe Utaka for the [Discord Bot Template](https://github.com/fellipeutaka/discord-bot-template)
[pr]: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request
[git]: https://git-scm.com
[node]: https://nodejs.org/
[ts]: https://www.typescriptlang.org/
[discord.js]: https://discord.js.org/
[eslint]: https://eslint.org/
[prettier]: https://prettier.io/
[ai-sdk]: https://ai-sdk.dev/
[bun]: https://bun.sh/
[exa]: https://exa.ai/
(QB_NEW_EN_OTHER_ERROR_IDS_5)
</details>
</details>
<details>
<summary>🪛 markdownlint-cli2 (0.17.2)</summary>
<details>
<summary>TODO.md</summary>
1-1: Inline HTML
Element: h1
(MD033, no-inline-html)
---
9-9: Ordered list item prefix
Expected: 5; Actual: 4; Style: 1/2/3
(MD029, ol-prefix)
---
11-11: Inline HTML
Element: a
(MD033, no-inline-html)
---
15-15: Inline HTML
Element: a
(MD033, no-inline-html)
---
27-27: Inline HTML
Element: a
(MD033, no-inline-html)
</details>
<details>
<summary>VECTOR.md</summary>
1-1: Inline HTML
Element: h1
(MD033, no-inline-html)
---
9-9: Ordered list item prefix
Expected: 5; Actual: 4; Style: 1/2/3
(MD029, ol-prefix)
---
11-11: Inline HTML
Element: a
(MD033, no-inline-html)
---
15-15: Inline HTML
Element: a
(MD033, no-inline-html)
</details>
</details>
<details>
<summary>🪛 GitHub Actions: CI</summary>
<details>
<summary>TODO.md</summary>
[warning] 1-1: Prettier formatting check warning. Code style issues found. Run 'prettier --write' to fix.
</details>
<details>
<summary>README.md</summary>
[warning] 1-1: Prettier formatting check warning. Code style issues found. Run 'prettier --write' to fix.
</details>
<details>
<summary>VECTOR.md</summary>
[warning] 1-1: Prettier formatting check warning. Code style issues found. Run 'prettier --write' to fix.
</details>
<details>
<summary>src/lib/ai/pinecone.ts</summary>
[warning] 17-17: ESLint: Expected parentheses around arrow function argument (arrow-parens)
---
[warning] 18-18: ESLint: Missing semicolon (semi)
---
[warning] 22-22: ESLint: Missing semicolon (semi)
---
[warning] 29-29: ESLint: Missing semicolon (semi)
---
[warning] 30-30: ESLint: Missing semicolon (semi)
---
[warning] 32-32: ESLint: Missing semicolon (semi)
---
[warning] 33-33: ESLint: Missing semicolon (semi)
---
[warning] 35-35: ESLint: Missing semicolon (semi)
---
[warning] 37-37: ESLint: Missing semicolon (semi)
</details>
</details>
<details>
<summary>🪛 ESLint</summary>
<details>
<summary>src/env.ts</summary>
[error] 1-1: Unable to resolve path to module '@t3-oss/env-core'.
(import-x/no-unresolved)
---
[error] 2-2: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
</details>
<details>
<summary>src/lib/ai/pinecone.ts</summary>
[error] 1-1: Unable to resolve path to module '@pinecone-database/pinecone'.
(import-x/no-unresolved)
</details>
</details>
</details>
<details>
<summary>🔇 Additional comments (4)</summary><blockquote>
<details>
<summary>README.md (2)</summary>
`49-63`: **LGTM! Clear documentation of Pinecone integration.**
The Memory section effectively documents the new Pinecone integration with specific technical requirements and environment variables. The specifications are clear and align with the codebase changes.
---
`64-66`: **Confirm MIT License Change Across Repository**
- LICENSE file now clearly specifies the MIT License.
- No remaining “AGPL” or “Affero” references were found in README.md, .txt, or .json files.
Please verify that this switch from AGPL-v3 to MIT is intentional and complete across all license declarations (e.g., any `package.json`, project metadata, or other documentation).
</details>
<details>
<summary>src/env.ts (1)</summary>
`31-33`: **LGTM! Proper Pinecone environment variable configuration.**
The Pinecone environment variables are correctly defined with appropriate validation. The `z.string().min(1)` ensures both the API key and index name are non-empty strings, which is appropriate for these required configuration values.
</details>
<details>
<summary>src/lib/ai/pinecone.ts (1)</summary>
`1-10`: **LGTM! Well-structured imports and type definition.**
The imports are appropriate for Pinecone integration, and the `Metadata` type effectively captures the essential fields needed for Discord message embeddings (url, text, chunk, hash).
</details>
</blockquote></details>
</details>
<!-- This is an auto-generated comment by CodeRabbit for review status -->
src/lib/ai/pinecone.ts
Outdated
const getMatchesFromEmbeddings = async (embeddings: number[], topK: number, namespace: string): Promise<ScoredPineconeRecord<Metadata>[]> => { | ||
const pinecone = new Pinecone(); | ||
|
||
const indexName = env.PINECONE_INDEX; | ||
const indexes = (await pinecone.listIndexes())?.indexes; | ||
if (!indexes || indexes.filter(i => i.name === indexName).length !== 1) { | ||
throw new Error(`Index ${indexName} does not exist`) | ||
} | ||
|
||
const index = pinecone.Index<Metadata>(indexName); | ||
const pineconeNamespace = index.namespace(namespace ?? '') | ||
|
||
try { | ||
const queryResult = await pineconeNamespace.query({ | ||
vector: embeddings, | ||
topK, | ||
includeMetadata: true, | ||
}) | ||
return queryResult.matches || [] | ||
} catch (e) { | ||
logger.error({ error: e }, "Error querying embeddings") | ||
throw new Error(`Error querying embeddings: ${e}`) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good implementation logic, but fix ESLint style violations.
The function implementation is well-structured with proper error handling and type safety. However, multiple ESLint style violations are causing CI warnings.
Apply these fixes for the ESLint violations:
- if (!indexes || indexes.filter(i => i.name === indexName).length !== 1) {
+ if (!indexes || indexes.filter((i) => i.name === indexName).length !== 1) {
- throw new Error(`Index ${indexName} does not exist`)
+ throw new Error(`Index ${indexName} does not exist`);
}
- const pineconeNamespace = index.namespace(namespace ?? '')
+ const pineconeNamespace = index.namespace(namespace ?? '');
try {
const queryResult = await pineconeNamespace.query({
vector: embeddings,
topK,
includeMetadata: true,
- })
- return queryResult.matches || []
+ });
+ return queryResult.matches || [];
} catch (e) {
- logger.error({ error: e }, "Error querying embeddings")
- throw new Error(`Error querying embeddings: ${e}`)
+ logger.error({ error: e }, "Error querying embeddings");
+ throw new Error(`Error querying embeddings: ${e}`);
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const getMatchesFromEmbeddings = async (embeddings: number[], topK: number, namespace: string): Promise<ScoredPineconeRecord<Metadata>[]> => { | |
const pinecone = new Pinecone(); | |
const indexName = env.PINECONE_INDEX; | |
const indexes = (await pinecone.listIndexes())?.indexes; | |
if (!indexes || indexes.filter(i => i.name === indexName).length !== 1) { | |
throw new Error(`Index ${indexName} does not exist`) | |
} | |
const index = pinecone.Index<Metadata>(indexName); | |
const pineconeNamespace = index.namespace(namespace ?? '') | |
try { | |
const queryResult = await pineconeNamespace.query({ | |
vector: embeddings, | |
topK, | |
includeMetadata: true, | |
}) | |
return queryResult.matches || [] | |
} catch (e) { | |
logger.error({ error: e }, "Error querying embeddings") | |
throw new Error(`Error querying embeddings: ${e}`) | |
} | |
} | |
const getMatchesFromEmbeddings = async ( | |
embeddings: number[], | |
topK: number, | |
namespace: string | |
): Promise<ScoredPineconeRecord<Metadata>[]> => { | |
const pinecone = new Pinecone(); | |
const indexName = env.PINECONE_INDEX; | |
const indexes = (await pinecone.listIndexes())?.indexes; | |
if (!indexes || indexes.filter((i) => i.name === indexName).length !== 1) { | |
throw new Error(`Index ${indexName} does not exist`); | |
} | |
const index = pinecone.Index<Metadata>(indexName); | |
const pineconeNamespace = index.namespace(namespace ?? ''); | |
try { | |
const queryResult = await pineconeNamespace.query({ | |
vector: embeddings, | |
topK, | |
includeMetadata: true, | |
}); | |
return queryResult.matches || []; | |
} catch (e) { | |
logger.error({ error: e }, "Error querying embeddings"); | |
throw new Error(`Error querying embeddings: ${e}`); | |
} | |
} |
🧰 Tools
🪛 GitHub Actions: CI
[warning] 17-17: ESLint: Expected parentheses around arrow function argument (arrow-parens)
[warning] 18-18: ESLint: Missing semicolon (semi)
[warning] 22-22: ESLint: Missing semicolon (semi)
[warning] 29-29: ESLint: Missing semicolon (semi)
[warning] 30-30: ESLint: Missing semicolon (semi)
[warning] 32-32: ESLint: Missing semicolon (semi)
[warning] 33-33: ESLint: Missing semicolon (semi)
[warning] 35-35: ESLint: Missing semicolon (semi)
🤖 Prompt for AI Agents
In src/lib/ai/pinecone.ts around lines 12 to 35, fix ESLint style violations by
ensuring consistent spacing and indentation, using strict equality checks (===)
instead of loose equality (!==), and properly formatting the code for
readability. Also, ensure that optional chaining and nullish coalescing are used
correctly, and that error handling logs the error object properly without string
concatenation. Review the entire function for any other ESLint warnings and
correct them accordingly.
Separate Deepgram code into it's files | ||
Implement Conversation history for Voice Chat, previous message memory + chat history. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Fix possessive/contracted “its/it’s” mix-ups
A few bullets use “it’s” (contraction) where the possessive “its” is intended. Keeps the list crisp and avoids copy-editing churn later.
- Separate Deepgram code into it's files
+ Separate Deepgram code into its files
- If a user interrupts it's replying, it will pause the current reply and reply to the other one with context.
+ If a user interrupts its reply, it will pause the current reply and respond to the other one with context.
Also applies to: 17-17
🧰 Tools
🪛 LanguageTool
[grammar] ~9-~9: There might be a problem here.
Context: ...alistic.
Separate Deepgram code into it's files
Implement Conversation history for Voice...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~10-~10: There might be a mistake here.
Context: ...istory for Voice Chat, previous message memory + chat history.
Add Commit Lint to enfo...
(QB_NEW_EN_OTHER)
[grammar] ~10-~10: Use correct spacing
Context: ...ce Chat, previous message memory + chat history.
Add Commit Lint to enforce strict commit me...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
🪛 markdownlint-cli2 (0.17.2)
9-9: Ordered list item prefix
Expected: 5; Actual: 4; Style: 1/2/3
(MD029, ol-prefix)
🤖 Prompt for AI Agents
In TODO.md at lines 9-10 and line 17, correct the misuse of "it's" where the
possessive "its" is intended. Replace all instances of the contraction "it's"
with the possessive form "its" to ensure grammatical accuracy in the bullet
points.
If a user interrupts it's replying, it will pause the current reply and reply to the other one with context. | ||
|
||
Have a small dashboard UI to modify the bots settings | ||
Add a slash chat command to chat with the AI on servers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Apostrophe missing in “bot’s settings”
Tiny typo that sneaks through linters; worth fixing now.
- Have a small dashboard UI to modify the bots settings
+ Have a small dashboard UI to modify the bot's settings
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
Have a small dashboard UI to modify the bots settings | |
Have a small dashboard UI to modify the bot's settings |
🧰 Tools
🪛 LanguageTool
[grammar] ~19-~19: There might be a problem here.
Context: ...Have a small dashboard UI to modify the bots settings
Add a slash chat command to chat with th...
(QB_NEW_EN_MERGED_MATCH)
🤖 Prompt for AI Agents
In TODO.md at line 19, the phrase "bots settings" is missing an apostrophe to
indicate possession. Update the text to "bot’s settings" by adding the
apostrophe after "bot" to correctly reflect that the settings belong to the bot.
When the user is typing increase the response speed by 0.5x. Also, use a different method for responding like a set WPM. | ||
|
||
Add CI/CD testing so pushing things to production don't break stuff. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Tone/clarity—replace “break stuff” with something actionable
The CI-driven checklist reads more professionally if the goal is explicit.
- Add CI/CD testing so pushing things to production don't break stuff.
+ Add CI/CD testing to prevent regressions when deploying to production.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
Add CI/CD testing so pushing things to production don't break stuff. | |
Add CI/CD testing to prevent regressions when deploying to production. |
🧰 Tools
🪛 LanguageTool
[grammar] ~25-~25: Use modal and auxiliary verbs correctly
Context: ...testing so pushing things to production don't break stuff.
Add context to when ...
(QB_NEW_EN_OTHER_ERROR_IDS_24)
[grammar] ~25-~25: Use correct spacing
Context: ...ushing things to production don't break stuff.
Add context to when the bot is triggered...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
🤖 Prompt for AI Agents
In TODO.md at line 25, replace the phrase "break stuff" with a more specific and
professional description of the goal, such as "cause production errors" or
"introduce bugs in production," to make the CI/CD testing objective clearer and
actionable.
TODO.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Refine the newly added TODOs for clarity & consistency
Consider making them imperative like the rest of the list and adding a bit of context so future readers know what “autobotting” refers to.
-Fix commands (broken on autobotting)
-Cleanup memory part later
+Fix command handling in autobot/selfbot mode
+Clean up legacy memory subsystem after refactor
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
Fix commands (broken on autobotting) | |
Cleanup memory part later | |
Fix command handling in autobot/selfbot mode | |
Clean up legacy memory subsystem after refactor |
🧰 Tools
🪛 LanguageTool
[grammar] ~34-~34: There might be a mistake here.
Context: ...eract with it.
Fix commands (broken on autobotting)
Cleanup memory part later
(QB_NEW_EN_OTHER)
[grammar] ~35-~35: Use a period to end declarative sentences
Context: ...en on autobotting)
Cleanup memory part later
(QB_NEW_EN_OTHER_ERROR_IDS_25)
🤖 Prompt for AI Agents
In TODO.md around lines 34 to 35, the newly added TODOs are not in imperative
form and lack context. Rewrite these TODOs to use imperative verbs and clarify
what "autobotting" means, so the tasks are clear and consistent with the rest of
the list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 25
♻️ Duplicate comments (25)
src/lib/ai/tools/get-weather.ts (2)
1-2
: Use stable module entry pointsThis is the same import resolution issue previously identified - both
'ai'
and'zod/v4'
imports use non-standard paths that won't resolve in most environments.
10-16
: Handle non-200 responses to avoid runtime exceptionsThe fetch implementation still lacks error handling for failed HTTP responses, which was previously identified as an issue that can cause runtime exceptions.
README.md (1)
29-29
: Update documentation to reflect selfbot architecture.The instructions still refer to creating a "Discord Bot" but the codebase has migrated to a selfbot model using
discord.js-selfbot-v13
. This creates confusion about the actual setup process.src/utils/voice/helpers/ai.ts (2)
3-3
: Duplicate: Unresolvable import pathThis import issue was already flagged in previous reviews.
10-14
: Duplicate: Use template literals instead of string concatenationThis string concatenation issue was already flagged in previous reviews.
src/lib/ai/tools/join-server.ts (1)
6-41
: Critical Discord ToS violation already identified.The implementation violates Discord's Terms of Service by using selfbot functionality. Error handling is also missing for API calls.
src/events/message-create/utils/relevance.ts (1)
1-7
: Imports correctly updated for new architecture.The import changes properly reflect the migration to the modular prompt system and selfbot library. The
RequestHints
import fix from the previous review has been correctly implemented.However, the ESLint error about the unresolved 'ai' module still needs to be addressed - ensure the package is properly installed and ESLint configuration includes the Node resolver.
src/lib/ai/providers.ts (2)
1-18
: Multi-provider import structure looks good.The imports properly support the fallback AI provider architecture with Google, Cohere, and OpenAI models.
However, similar to other files, ESLint cannot resolve the AI SDK modules. Ensure all packages are installed and ESLint is configured to resolve Node modules properly.
20-22
: Fix the non-null assertion to prevent runtime errors.The non-null assertion on
env.GOOGLE_GENERATIVE_AI_API_KEY!
could cause runtime errors if the environment variable is not set, even though it's marked as optional in the schema.-const google = createGoogleGenerativeAI({ - apiKey: env.GOOGLE_GENERATIVE_AI_API_KEY!, -}); +const google = createGoogleGenerativeAI({ + apiKey: env.GOOGLE_GENERATIVE_AI_API_KEY ?? (() => { + throw new Error('GOOGLE_GENERATIVE_AI_API_KEY environment variable is required'); + })(), +});VECTOR.md (1)
1-24
: Fix markdown formatting and spelling errors to unblock CI.The document still contains multiple formatting and spelling errors that will cause CI failures. Here are the key fixes needed:
# Vector + Let's use Pinecone for the following: + -1. As we use the AI SDK, we will use OpenAI compatible models for embedding, like embedding large (use models, embedding in models.ts), same with searching for data. -2. We use a dense index in Pinecone for semantic search, matching the output of modern embedding models and the bot's use case. (https://docs.pinecone.io/guides/index-data/create-an-index#bring-your-own-vectors), include metadata like timestamp, user, server, channel, etc. So when searching we can limit the search to a specific server, channel, etc. (https://docs.pinecone.io/guides/search/filter-by-metadata#search-with-a-metadata-filter) +1. As we use the AI SDK, we will use OpenAI-compatible models for embedding, like embedding-large (use models, embedding in models.ts), same with searching for data. +2. We use a dense index in Pinecone for semantic search, matching the output of modern embedding models and the bot's use case. Include metadata like timestamp, user, server, channel, etc. So when searching we can limit the search to a specific server, channel, etc. 3. We do NOT need to chunk the data as discord messages are already short and concise. -4. When a message is deleted or edited, we should remove the embedding from the index, or update it. (https://docs.pinecone.io/guides/index-data/data-modeling#delete-chunks, https://docs.pinecone.io/guides/index-data/data-modeling#update-chunks). Have a way to easily connect message and embedding id. -5. After all this we can upsert the embeddings to the index. (https://docs.pinecone.io/guides/index-data/upsert-data#upsert-dense-vectors) (https://docs.pinecone.io/guides/index-data/indexing-overview#bring-your-own-vectors) -6. Setup a hybrid search index (https://docs.pinecone.io/guides/search/hybrid-search#use-a-single-hybrid-index) +4. When a message is deleted or edited, we should remove the embedding from the index, or update it. Have a way to easily connect message and embedding IDs. +5. After all this we can upsert the embeddings to the index. +6. Set up a hybrid search index. + # Searches + -- When searching have a sophisticated algo (bob), check through server, recent messages, and a lot of context as well so we get the data. w/metadata timeframes, users etc. (https://docs.pinecone.io/guides/get-started/quickstart#5-semantic-search) +- When searching, have a sophisticated algorithm, check through the server, recent messages, and a lot of context as well so we get the data. Include metadata timeframes, users etc. + # TODO + Learn about namespaces -Learn about rerankinig (https://docs.pinecone.io/guides/get-started/quickstart#6-rerank-results) -Look at bob code (https://docs.pinecone.io/guides/get-started/quickstart#7-improve-results) -Look at AI SDK pinecone example so we can implement it - -3-large-textembbeding +Learn about reranking +Look at reference code +Look at the AI SDK Pinecone example so we can implement itThe mysterious "3-large-textembbeding" text at the end should be removed as it appears to be accidental input.
src/utils/context.ts (1)
3-3
: Import structure is correct now - past issue resolved.The
RequestHints
type is now correctly imported directly from@/types
instead of from the prompts module, which resolves the previous TypeScript compilation error.TODO.md (5)
9-10
: Fix possessive/contracted "its/it's" mix-ups.As previously noted, these lines use "it's" (contraction) where the possessive "its" is intended.
- Separate Deepgram code into it's files + Separate Deepgram code into its files - Implement Conversation history for Voice Chat, previous message memory + chat history. + Implement conversation history for Voice Chat, previous message memory + chat history.
17-17
: Fix possessive "its" usage.- If a user interrupts it's replying, it will pause the current reply and reply to the other one with context. + If a user interrupts its reply, it will pause the current reply and respond to the other one with context.
19-19
: Add missing apostrophe in "bot's settings".- Have a small dashboard UI to modify the bots settings + Have a small dashboard UI to modify the bot's settings
25-25
: Replace "break stuff" with professional language.- Add CI/CD testing so pushing things to production don't break stuff. + Add CI/CD testing to prevent regressions when deploying to production.
34-35
: Refine newly added TODOs for clarity and consistency.These TODOs lack context and don't follow the imperative form used elsewhere in the list.
- Fix commands (broken on autobotting) - Cleanup memory part later + Fix command handling in autobot/selfbot mode + Clean up legacy memory subsystem after refactorsrc/lib/ai/tools/start-dm.ts (3)
6-82
: Critical: This implementation violates Discord's Terms of Service.This selfbot functionality violates Discord's Terms of Service. Automated DM sending using user accounts is explicitly prohibited and can result in account termination.
43-52
: Consider rate limiting for friend requests.Automatically sending friend requests when DMs fail could trigger Discord's spam detection.
74-80
: Improve error logging specificity.The generic error handling could benefit from more specific error information to aid debugging.
src/events/message-create/utils/respond.ts (2)
5-5
: Critical: Integration of ToS-violating selfbot tools.The integration of
joinServer
andstartDM
tools introduces Discord Terms of Service violations into the AI response system. These tools enable automated user account actions that Discord explicitly prohibits.Consider removing these tools or implementing equivalent functionality through Discord's official bot API to maintain compliance.
Also applies to: 10-10, 35-36, 45-46
85-90
: Consider more specific error handling.The generic error handling could provide more context for debugging tool execution failures.
} catch (e) { + logger.error({ error: e, messageId: msg.id, author: msg.author.username }, 'Failed to generate response'); return { success: false, - error: (e as Error)?.message, + error: (e as Error)?.message || 'An unexpected error occurred', }; }src/config.ts (2)
12-12
: Simplify speedFactor valueThe multiplication
180 * 180
makes the actual value less clear. Consider using the computed value directly.- speedFactor: 180 * 180, + speedFactor: 32400,
17-40
: UseActivityType
enum instead of raw numbersTo improve readability and prevent magic numbers, replace the numeric
type
values with theActivityType
enum from discord.js-selfbot-v13.+import { ActivityType } from 'discord.js-selfbot-v13'; import type { Activity } from './types'; export const activities: Activity[] = [ { - type: 5, + type: ActivityType.Competing, name: 'painting', image: 'https://pbs.twimg.com/media/GrGH5PIaAAI7aLu?format=png&name=360x360', }, { - type: 2, + type: ActivityType.Listening, name: 'music', image: 'https://pbs.twimg.com/media/GtTOrD7bMAEfahJ?format=png&name=medium', }, { - type: 3, + type: ActivityType.Watching, name: 'tv', image: 'https://pbs.twimg.com/media/GuaO0GVbEAA3xHa?format=png&name=small', }, { - type: 0, + type: ActivityType.Playing, name: 'in the gym', image: 'https://pbs.twimg.com/media/GuvLw79XQAACrp3?format=png&name=900x900', }, ];package.json (2)
21-21
:bun run src/deploy-commands.ts
script is dead code
src/deploy-commands.ts
was deleted in this PR, yet thedeploy
npm script still references it –bun run
will exit with code 1.Delete or replace the script.
- "deploy": "bun run src/deploy-commands.ts", + "deploy": "echo \"No longer applicable\"",
36-37
: Library-mismatch:@discordjs/voice
requiresdiscord.js@14
, not a self-botYou now depend on
discord.js-selfbot-v13
(v13 API).
@discordjs/[email protected]
→ hard-pinsdiscord.js@^14
peer-dependency.
This combination will break at runtime and during install.Either:
- Remove voice (+ its helpers), or
- Revert to normal
discord.js@14
instead of the self-bot fork.Also applies to: 50-50
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (38)
.cspell.json
(1 hunks).env.example
(2 hunks)Dockerfile
(1 hunks)README.md
(1 hunks)TODO.md
(1 hunks)VECTOR.md
(1 hunks)package.json
(1 hunks)src/config.ts
(1 hunks)src/events/message-create/index.ts
(1 hunks)src/events/message-create/utils/relevance.ts
(1 hunks)src/events/message-create/utils/respond.ts
(1 hunks)src/lib/ai/prompts.ts
(0 hunks)src/lib/ai/prompts/core.ts
(1 hunks)src/lib/ai/prompts/examples.ts
(1 hunks)src/lib/ai/prompts/index.ts
(1 hunks)src/lib/ai/prompts/personality.ts
(1 hunks)src/lib/ai/prompts/tasks.ts
(1 hunks)src/lib/ai/prompts/tools.ts
(1 hunks)src/lib/ai/providers.ts
(1 hunks)src/lib/ai/tools/get-user-info.ts
(1 hunks)src/lib/ai/tools/get-weather.ts
(1 hunks)src/lib/ai/tools/join-server.ts
(1 hunks)src/lib/ai/tools/react.ts
(1 hunks)src/lib/ai/tools/report.ts
(1 hunks)src/lib/ai/tools/search-memories.ts
(1 hunks)src/lib/ai/tools/search-web.ts
(1 hunks)src/lib/ai/tools/start-dm.ts
(1 hunks)src/lib/kv.ts
(1 hunks)src/lib/pinecone/index.ts
(1 hunks)src/lib/pinecone/queries.ts
(1 hunks)src/lib/validators/index.ts
(1 hunks)src/lib/validators/pinecone.ts
(1 hunks)src/tests/pinecone.ts
(1 hunks)src/types/index.ts
(1 hunks)src/utils/context.ts
(1 hunks)src/utils/messages.ts
(1 hunks)src/utils/tokenize-messages.ts
(1 hunks)src/utils/voice/helpers/ai.ts
(1 hunks)
💤 Files with no reviewable changes (1)
- src/lib/ai/prompts.ts
🧰 Additional context used
🧬 Code Graph Analysis (11)
src/tests/pinecone.ts (1)
src/lib/pinecone/queries.ts (1)
queryMemories
(24-83)
src/utils/voice/helpers/ai.ts (2)
src/lib/ai/prompts/index.ts (1)
systemPrompt
(21-55)src/lib/ai/providers.ts (1)
myProvider
(38-54)
src/lib/ai/tools/search-memories.ts (1)
src/lib/pinecone/queries.ts (1)
searchMemories
(85-124)
src/events/message-create/utils/relevance.ts (4)
src/types/request.ts (1)
RequestHints
(3-12)src/lib/validators/probability.ts (2)
Probability
(17-17)probabilitySchema
(3-15)src/lib/ai/providers.ts (1)
myProvider
(38-54)src/lib/ai/prompts/index.ts (1)
systemPrompt
(21-55)
src/lib/pinecone/index.ts (1)
src/env.ts (1)
env
(4-56)
src/lib/ai/prompts/index.ts (6)
src/types/request.ts (1)
RequestHints
(3-12)src/lib/ai/prompts/core.ts (1)
corePrompt
(1-17)src/lib/ai/prompts/personality.ts (1)
personalityPrompt
(1-14)src/lib/ai/prompts/examples.ts (1)
examplesPrompt
(3-66)src/lib/ai/prompts/tools.ts (1)
memoryPrompt
(1-9)src/lib/ai/prompts/tasks.ts (2)
replyPrompt
(1-8)relevancePrompt
(10-38)
src/utils/context.ts (5)
src/types/request.ts (1)
RequestHints
(3-12)src/lib/queries.ts (2)
getMessagesByChannel
(11-28)getChannelName
(30-42)src/utils/messages.ts (1)
convertToModelMessages
(9-31)src/utils/time.ts (1)
getTimeInCity
(4-11)src/config.ts (1)
timezone
(6-6)
src/lib/kv.ts (1)
src/env.ts (1)
env
(4-56)
src/lib/ai/tools/search-web.ts (1)
src/lib/search.ts (1)
exa
(10-10)
src/lib/ai/providers.ts (1)
src/env.ts (1)
env
(4-56)
src/config.ts (1)
src/types/activity.ts (1)
Activity
(1-5)
🪛 ESLint
src/lib/ai/tools/get-weather.ts
[error] 1-1: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 2-2: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/lib/ai/tools/report.ts
[error] 2-2: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/utils/voice/helpers/ai.ts
[error] 3-3: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
src/lib/ai/tools/search-memories.ts
[error] 3-3: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/events/message-create/utils/relevance.ts
[error] 6-6: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
src/lib/pinecone/index.ts
[error] 2-2: Unable to resolve path to module '@pinecone-database/pinecone'.
(import-x/no-unresolved)
src/events/message-create/utils/respond.ts
[error] 14-14: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
src/lib/ai/tools/react.ts
[error] 1-1: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 3-3: Unable to resolve path to module 'zod'.
(import-x/no-unresolved)
src/lib/ai/tools/join-server.ts
[error] 2-2: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/utils/context.ts
[error] 7-7: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/utils/messages.ts
[error] 7-7: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/events/message-create/index.ts
[error] 12-12: Unable to resolve path to module 'discord.js-selfbot-v13'.
(import-x/no-unresolved)
src/lib/kv.ts
[error] 2-2: Unable to resolve path to module '@upstash/ratelimit'.
(import-x/no-unresolved)
[error] 3-3: Unable to resolve path to module '@upstash/redis'.
(import-x/no-unresolved)
src/lib/ai/tools/search-web.ts
[error] 3-3: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/lib/validators/pinecone.ts
[error] 1-1: Unable to resolve path to module 'zod'.
(import-x/no-unresolved)
src/lib/ai/providers.ts
[error] 1-1: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module '@ai-sdk/cohere'.
(import-x/no-unresolved)
[error] 5-5: Unable to resolve path to module '@ai-sdk/google'.
(import-x/no-unresolved)
[error] 6-6: Unable to resolve path to module '@ai-sdk/openai'.
(import-x/no-unresolved)
[error] 7-7: Unable to resolve path to module 'ai-fallback'.
(import-x/no-unresolved)
src/lib/ai/tools/get-user-info.ts
[error] 2-2: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
src/lib/pinecone/queries.ts
[error] 4-4: Unable to resolve path to module '@pinecone-database/pinecone'.
(import-x/no-unresolved)
[error] 5-5: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 6-6: Unable to resolve path to module 'bun'.
(import-x/no-unresolved)
src/lib/ai/tools/start-dm.ts
[error] 2-2: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 4-4: Unable to resolve path to module 'zod/v4'.
(import-x/no-unresolved)
🪛 LanguageTool
README.md
[grammar] ~3-~3: Use correct spacing
Context: ...">AI Discord Bot
📋 Table of Contents
- 🤖 Introduction
- 🚀 ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~9-~9: Use correct spacing
Context: ...tarted)
4. 🧠 Memory
5. 📝 License
🤖 Introduction
A human-like bot ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~11-~11: Use correct spacing
Context: ...icense)
🤖 Introduction
A human-like bot that is almost indistin...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~13-~13: Use correct spacing
Context: ...is almost indistinguishable from a real person.
🚀 Tech Stack
This project was de...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~15-~15: Use correct spacing
Context: ...son.
🚀 Tech Stack
This project was developed with the foll...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~17-~17: There might be a mistake here.
Context: ...roject was developed with the following technologies:
- [Vercel AI SDK][ai-sdk]
- [Exa AI][exa]...
(QB_NEW_EN_OTHER)
[grammar] ~25-~25: Use correct spacing
Context: ...]
- [Bun][bun]
- [ESLint][eslint]
- [Prettier][prettier]
📚 Getting Started
To clone and r...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~27-~27: Use correct spacing
Context: ...## 📚 Getting Started
To clone and run this application, first...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[locale-violation] ~29-~29: In American English, ‘afterward’ is the preferred variant. ‘Afterwards’ is more commonly used in British English and other dialects.
Context: ...idpolice.com/how-to-make-discord-bot/). Afterwards, you will need [Git][git] and [Bun][bun...
(AFTERWARDS_US)
[grammar] ~29-~29: Use correct spacing
Context: ...][git] and [Bun][bun] installed on your computer.
From your command line:
# Cl...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~31-~31: There might be a mistake here.
Context: ... on your computer.
From your command line:
```bash
# Clone this repository
$ git clone https://github.com/techwithanirudh/discord-ai-bot.git
# Install dependencies
$ bun install
Next, copy the .env.example fil...
(QB_NEW_EN_OTHER)
[grammar] ~41-~41: Use correct spacing
Context: ...me it to .env, and add your environment variables.
Great! Now you just need to start the developm...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~42-~42: Use correct spacing
Context: ... you just need to start the development server.
# Start server
$ bun run dev
🧠 Memory
This bot uses Pinecone ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~49-~49: Use correct spacing
Context: ... run dev
## <a name="memory">🧠 Memory</a>
This bot uses Pinecone to store memory. ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~51-~51: Use correct spacing
Context: ...t variable to the name of your Pinecone index.
Set the `PINECONE_API_KEY` environment v...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~53-~53: Use correct spacing
Context: ...vironment variable to your Pinecone API key.
Then, create a Pinecone index and set th...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~55-~55: There might be a problem here.
Context: ...t variable to the name of your Pinecone index.
Spec:
- Pinecone index should be dense
- Dimen...
(QB_NEW_EN_MERGED_MATCH)
---
[grammar] ~59-~59: There might be a mistake here.
Context: ...
Spec:
- Pinecone index should be dense
- Dimension: 1536
- Metric: dotproduct
-...
(QB_NEW_EN_OTHER)
---
[grammar] ~61-~61: There might be a problem here.
Context: ...x should be dense
- Dimension: 1536
- Metric: dotproduct
- Spec: aws, us-east-1
- Namespace: `...
(QB_NEW_EN_MERGED_MATCH)
---
[grammar] ~63-~63: Use correct spacing
Context: ...: dotproduct
- Spec: aws, us-east-1
- Namespace: `default`
## <a name="license">📝 License</a>
This project is under ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~65-~65: Use correct spacing
Context: ...e: `default`
## <a name="license">📝 License</a>
This project is under the MIT license. S...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~67-~67: Use correct spacing
Context: ...license. See the [LICENSE](LICENSE) for details.
> Credit to Fellipe Utaka for the [Discord...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~69-~69: Use correct spacing
Context: ...t to Fellipe Utaka for the [Discord Bot Template](https://github.com/fellipeutaka/discord-bot-template)
[pr]: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request
[git]: https://git-scm.com
[node]: https://nodejs.org/
[ts]: https://www.typescriptlang.org/
[discord.js]: https://discord.js.org/
[eslint]: https://eslint.org/
[prettier]: https://prettier.io/
[ai-sdk]: https://ai-sdk.dev/
[bun]: https://bun.sh/
[exa]: https://exa.ai/
(QB_NEW_EN_OTHER_ERROR_IDS_5)
</details>
<details>
<summary>TODO.md</summary>
[style] ~13-~13: The phrasing ‘more easy’ can sound awkward and informal. Consider using a comparative adjective or other alternative.
Context: ...).
Refactor the channels command to be more easy to use, with deny and allow lists.
D...
(MORE_EASY_N_CLEAR)
</details>
<details>
<summary>VECTOR.md</summary>
[grammar] ~1-~1: Use correct spacing
Context: # Vector
Let's use Pinecone for the following:
...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
---
[grammar] ~3-~3: There might be a mistake here.
Context: # Vector
Let's use Pinecone for the following:
1. As we use the AI SDK, we will use OpenA...
(QB_NEW_EN_OTHER)
---
[grammar] ~5-~5: Use hyphens correctly
Context: ...
1. As we use the AI SDK, we will use OpenAI compatible models for embedding, like em...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
---
[grammar] ~5-~5: There might be a problem here.
Context: ...els for embedding, like embedding large (use models, embedding in models.ts), same with sear...
(QB_NEW_EN_MERGED_MATCH)
---
[grammar] ~5-~5: There might be a problem here.
Context: ...bedding large (use models, embedding in models.ts), same with searching for data.
2. We us...
(QB_NEW_EN_MERGED_MATCH)
---
[grammar] ~6-~6: Use a comma after introductory words or phrases
Context: ...mp, user, server, channel, etc. So when searching we can limit the search to a specific s...
(QB_NEW_EN_OTHER_ERROR_IDS_19)
---
[grammar] ~7-~7: Use a comma after introductory words or phrases
Context: ...filter)
3. We do NOT need to chunk the data as discord messages are already short a...
(QB_NEW_EN_OTHER_ERROR_IDS_19)
---
[grammar] ~8-~8: There might be a mistake here.
Context: ...we should remove the embedding from the index, or update it. (https://docs.pinecone.i...
(QB_NEW_EN_OTHER)
---
[grammar] ~8-~8: Make sure to use plural and singular nouns correctly
Context: ...e-chunks). Have a way to easily connect message and embedding id.
5. After all this we...
(QB_NEW_EN_OTHER_ERROR_IDS_10)
---
[grammar] ~8-~8: There might be a mistake here.
Context: ...to easily connect message and embedding id.
5. After all this we can upsert the em...
(QB_NEW_EN_OTHER)
---
[grammar] ~10-~10: Use the right verb tense
Context: ...ng-overview#bring-your-own-vectors)
6. Setup a hybrid search index (https://docs.pin...
(QB_NEW_EN_OTHER_ERROR_IDS_13)
---
[grammar] ~14-~14: Use a comma after introductory words or phrases
Context: ...e-hybrid-index)
# Searches
- When searching have a sophisticated algo (bob), check ...
(QB_NEW_EN_OTHER_ERROR_IDS_19)
---
[grammar] ~14-~14: There might be a mistake here.
Context: ...
- When searching have a sophisticated algo (bob), check through server, recent mes...
(QB_NEW_EN_OTHER)
---
[grammar] ~14-~14: Use articles correctly
Context: ...sophisticated algo (bob), check through server, recent messages, and a lot of context a...
(QB_NEW_EN_OTHER_ERROR_IDS_11)
---
[grammar] ~18-~18: There might be a mistake here.
Context: ...mantic-search)
# TODO
Learn about namespaces
Learn about rerankinig (https://docs.pin...
(QB_NEW_EN_OTHER)
---
[grammar] ~20-~20: There might be a mistake here.
Context: .../quickstart#6-rerank-results)
Look at bob code (https://docs.pinecone.io/guides/g...
(QB_NEW_EN_OTHER)
---
[grammar] ~21-~21: Use articles correctly
Context: .../quickstart#7-improve-results)
Look at AI SDK pinecone example so we can implemen...
(QB_NEW_EN_OTHER_ERROR_IDS_11)
---
[grammar] ~21-~21: There might be a mistake here.
Context: ...DK pinecone example so we can implement it
3-large-textembbeding
(QB_NEW_EN_OTHER)
---
[grammar] ~23-~23: There might be a problem here.
Context: ...ne example so we can implement it
3-large-textembbeding
(QB_NEW_EN_MERGED_MATCH)
</details>
</details>
<details>
<summary>🪛 markdownlint-cli2 (0.17.2)</summary>
<details>
<summary>README.md</summary>
1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
---
50-50: Bare URL used
(MD034, no-bare-urls)
</details>
<details>
<summary>VECTOR.md</summary>
1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
</details>
</details>
<details>
<summary>🪛 GitHub Actions: CI</summary>
<details>
<summary>src/utils/voice/helpers/ai.ts</summary>
[error] 11-11: TypeScript error TS2345: Argument of type '{ selectedChatModel: string; }' is not assignable to parameter of type '{ selectedChatModel: string; requestHints: RequestHints; }'. Missing required property 'requestHints'.
</details>
<details>
<summary>TODO.md</summary>
[error] 55-55: cspell: Unknown word 'liek' detected; suggested fix: 'like'.
</details>
<details>
<summary>src/utils/messages.ts</summary>
[error] 12-12: TypeScript error TS2322: Type '{ role: "user" | "assistant"; content: (ImagePart | { type: "text"; text: string; })[]; createdAt: Date; }[]' is not assignable to type 'ModelMessage[]'. Role property type mismatch between 'user' | 'assistant' and expected 'assistant'.
</details>
<details>
<summary>src/lib/validators/pinecone.ts</summary>
[error] 3-3: cspell: Unknown word 'Jsonify' detected.
</details>
<details>
<summary>src/lib/ai/providers.ts</summary>
[warning] 21-21: ESLint: Forbidden non-null assertion (@typescript-eslint/no-non-null-assertion)
</details>
<details>
<summary>src/lib/pinecone/queries.ts</summary>
[warning] 13-13: ESLint: Unexpected any. Specify a different type (@typescript-eslint/no-explicit-any)
---
[warning] 35-35: ESLint: Unexpected any. Specify a different type (@typescript-eslint/no-explicit-any)
</details>
</details>
<details>
<summary>🪛 Checkov (3.2.334)</summary>
<details>
<summary>Dockerfile</summary>
[LOW] 6-6: Ensure that APT isn't used
(CKV_DOCKER_9)
---
[LOW] 1-46: Ensure that HEALTHCHECK instructions have been added to container images
(CKV_DOCKER_2)
---
[LOW] 8-14: Ensure that sudo isn't used
(CKV2_DOCKER_1)
</details>
</details>
<details>
<summary>🪛 Hadolint (2.12.0)</summary>
<details>
<summary>Dockerfile</summary>
[warning] 6-6: Do not use apt as it is meant to be a end-user tool, use apt-get or apt-cache instead
(DL3027)
---
[info] 8-8: Multiple consecutive `RUN` instructions. Consider consolidation.
(DL3059)
---
[warning] 8-8: Do not use apt as it is meant to be a end-user tool, use apt-get or apt-cache instead
(DL3027)
---
[warning] 21-21: Use WORKDIR to switch to a directory
(DL3003)
---
[warning] 26-26: Use WORKDIR to switch to a directory
(DL3003)
</details>
</details>
</details>
<details>
<summary>🔇 Additional comments (46)</summary><blockquote>
<details>
<summary>src/lib/ai/tools/get-weather.ts (1)</summary>
`4-9`: **LGTM: Schema property standardization**
The rename from `parameters` to `inputSchema` improves consistency across the AI tools subsystem and aligns with the updated schema naming conventions.
</details>
<details>
<summary>.env.example (2)</summary>
`23-23`: **LGTM: Cohere integration support**
Good addition of the Cohere API key configuration, properly commented out by default as expected in an example file.
---
`44-44`: **LGTM: Mem0 to Pinecone migration**
Appropriately commenting out the Mem0 API key as part of the migration to Pinecone for memory storage. Keeping it commented rather than removed provides useful context.
</details>
<details>
<summary>src/types/index.ts (1)</summary>
`1-4`: **LGTM: Clean type consolidation**
Good centralization of type exports from the three modules. The trailing newline issue from the previous review appears to be resolved.
</details>
<details>
<summary>src/lib/validators/index.ts (1)</summary>
`1-2`: **LGTM: Pinecone validator integration**
Clean addition of the Pinecone validator exports to support the new memory system integration. Good alphabetical ordering of exports.
</details>
<details>
<summary>src/tests/pinecone.ts (2)</summary>
`1-1`: **LGTM: Correct import path**
Proper import using the project's path alias convention.
---
`3-6`: **LGTM: Reasonable test setup**
Good test query with appropriate options. Using `ignoreRecent: false` makes sense for testing to ensure all relevant memories are retrieved.
</details>
<details>
<summary>README.md (3)</summary>
`8-9`: **LGTM: Table of contents numbering fixed.**
The duplicate numbering issue for Memory and License sections has been resolved - License is now correctly numbered as "5."
---
`67-67`: **License change from AGPL-v3 to MIT.**
The license has been changed from AGPL-v3 to MIT. Ensure this change is intentional and that all contributors agree to the license change.
---
`49-64`: **Pinecone configuration verified**
- In `src/lib/pinecone/index.ts`, the index is created with `dimension: 1536` and `metric: 'dotproduct'`.
- In `src/lib/ai/providers.ts`, `'small-model'` is mapped to OpenAI’s `text-embedding-3-small`, which produces 1536-dimensional vectors.
- Using the dot-product metric for un-normalized OpenAI embeddings is appropriate for similarity searches.
No changes needed.
</details>
<details>
<summary>src/lib/kv.ts (2)</summary>
`19-22`: **LGTM: Simplified Redis keys structure.**
The removal of `allowedChannels` key aligns with the architectural changes removing channel-based restrictions and the channels command.
---
`14-14`: **Review Rate Limit Increase**
The sliding window limiter in src/lib/kv.ts has been raised from 7 → 30 requests per 30 seconds:
- Definition: `src/lib/kv.ts`
```ts
limiter: Ratelimit.slidingWindow(30, '30 s'),
- Usage:
src/events/message-create/index.ts
const { success } = await ratelimit.limit(redisKeys.channelCount(ctxId));
Please verify that 30 requests/30 s per channel matches your expected message volume and doesn’t weaken abuse protection.
src/lib/ai/tools/report.ts (2)
3-3
: LGTM: Type migration to discord.js-selfbot-v13.
The update from MinimalContext
to Message
from discord.js-selfbot-v13
aligns with the broader migration to the selfbot architecture.
10-10
: LGTM: Property renamed for consistency.
The rename from parameters
to inputSchema
maintains consistency with other AI tools in the codebase.
src/lib/ai/prompts/tools.ts (1)
1-9
: LGTM: Clear memory usage instructions.
The memoryPrompt
provides clear guidance for the AI on memory limitations and search strategies. The recommendation to use 4-5 different queries with varied phrasing is a good practice for improving retrieval accuracy in vector search systems.
src/lib/ai/tools/react.ts (1)
5-27
: LGTM: Well-structured tool implementation.
The react
tool follows the established pattern with proper input validation, error handling, and consistent response structure.
src/lib/ai/tools/search-web.ts (2)
8-8
: LGTM: Schema property renamed to match updated API
The change from parameters
to inputSchema
aligns with the broader tool API standardization across the codebase.
10-15
: Verify semantic change from .nullable()
to .optional()
The change from .nullable()
to .optional()
has different semantics - .nullable()
allows null
values while .optional()
allows undefined
. Ensure this aligns with the expected API behavior for the specificDomain
parameter.
src/lib/ai/prompts/core.ts (1)
1-17
: Well-structured core prompt with comprehensive Discord guidelines
The prompt provides clear instructions for Discord interactions, responsible user pinging behavior, and maintains consistent persona. The behavioral guidelines effectively balance functionality with user experience.
src/lib/ai/prompts/personality.ts (3)
7-7
: Consider implications of deliberately wrong answers
The instruction to "always give wrong answers or say something funny" to serious questions could lead to harmful misinformation or frustrate users seeking genuine help. Consider adding context about when this behavior is appropriate.
11-11
: Review appropriateness of explicit personality traits
The personality includes explicit references ("kinda horny") that may not be suitable for all Discord servers or user interactions. Consider whether this aligns with the intended use cases and community guidelines.
1-14
: Well-defined personality with consistent character traits
The personality prompt effectively establishes a distinct character voice with clear behavioral patterns and communication style guidelines.
src/lib/ai/tools/search-memories.ts (2)
16-38
: Excellent error handling and logging implementation
The tool properly handles errors, provides meaningful logging, and returns consistent response formats with success/failure indicators. The data transformation preserves essential information while keeping the response clean.
26-29
: Good data transformation preserving essential fields
The mapping extracts only the necessary score
and metadata
fields, providing a clean interface while preserving the semantic search relevance information.
src/lib/ai/tools/get-user-info.ts (1)
6-63
: Well-implemented user information tool.
The implementation demonstrates good practices:
- Proper error handling with try-catch blocks
- Logical fallback from ID to username search
- Appropriate handling of ambiguous username matches
- Comprehensive user data return structure
- Good error logging
src/utils/tokenize-messages.ts (1)
1-11
: Good simplification by removing external dependency.
The refactor successfully removes the compromise
library dependency with a focused regex-based implementation. The sentence splitting logic handles common cases well.
src/events/message-create/utils/relevance.ts (2)
9-13
: LGTM! Function signature simplified appropriately.
The removal of the memories
parameter aligns with the new architecture where memory handling is integrated into the prompt system rather than being passed separately.
15-32
: Enhanced error handling and clean integration.
The function implementation correctly uses the new prompt system and includes improved error logging. The fallback probability of 0.5 with a user-friendly error message is appropriate for the relevance assessment use case.
src/lib/pinecone/index.ts (1)
5-5
: LGTM! Pinecone client properly initialized.
The client initialization correctly uses the validated environment variable from the schema.
src/lib/ai/providers.ts (2)
24-36
: Excellent fallback model configuration.
The fallback setup with multiple Google Gemini models and Cohere provides good redundancy. The error logging and 60-second model reset interval are well-configured to handle provider failures gracefully.
38-54
: Well-structured provider configuration for multi-modal AI.
The provider setup appropriately separates concerns with different models for chat, reasoning, and relevance tasks. The inclusion of OpenAI embedding models supports the new Pinecone memory system effectively.
src/utils/context.ts (1)
9-40
: LGTM! Clean refactor removing memory dependencies.
The function has been streamlined effectively:
- Correctly migrated to use
discord.js-selfbot-v13
types - Removed memory-related complexity while maintaining core functionality
- Proper handling of messages and hints construction
- Good separation of concerns with fallback logic for both messages and hints
The channel casting on line 19 is appropriate given the Discord.js type system.
TODO.md (1)
37-59
: LGTM! Comprehensive roadmap for system improvements.
The new TODO items provide a clear roadmap for:
- Migration to better tooling (lefthook instead of husky)
- Memory system improvements with proper typing and querying
- Enhanced AI capabilities with tool calling and WPM calculations
- Better Discord integration with improved attachment handling and user mention processing
- System reliability improvements with logging and metadata handling
These align well with the broader system refactor toward Pinecone-based memory and selfbot architecture.
src/lib/ai/prompts/tasks.ts (2)
1-8
: LGTM! Clear and effective reply guidance.
The replyPrompt
provides excellent instructions for natural conversation:
- Emphasizes casual, non-formal responses
- Includes security measures against prompt injection attempts
- Clever instruction to include intentional imperfections for authenticity
- Good fallback suggestion to use the "react" tool when unsure
The task-based formatting with XML tags is clean and consistent.
10-38
: Excellent relevance assessment framework.
The relevancePrompt
provides a comprehensive and practical framework:
- Clear criteria for what constitutes relevance vs. noise
- Specific examples with scoring rationale
- Good guidance on avoiding over-participation
- Practical advice about silence and conversation flow
- Includes specific user ID examples to avoid ping confusion
The casual tone ("nah bro", "Be cool") matches the bot's personality while maintaining clarity.
src/lib/validators/pinecone.ts (2)
3-16
: LGTM! Clever JSON string handling utility.
The Jsonify
helper elegantly handles the dual nature of metadata that can be either objects or JSON strings:
- Accepts both native objects and JSON strings
- Proper error handling for invalid JSON
- Consistently transforms output to JSON strings
- Good reusability through generic typing
17-57
: LGTM! Well-structured metadata validation system.
The schema architecture is excellent:
- Clear separation between guild and channel schemas
- Proper use of inheritance with
BaseMetadataSchema
- Type discrimination for different metadata types (tool vs chat)
- Comprehensive type exports for both input and output
- Good use of optional fields where appropriate
The schemas provide strong type safety for the Pinecone integration while maintaining flexibility for different use cases.
src/events/message-create/utils/respond.ts (1)
53-81
: Well-implemented async memory storage for tool calls.
The onStepFinish
callback properly handles:
- Parallel processing with
Promise.all
- Null checks for tool calls and results
- Comprehensive metadata storage including channel, guild, and user context
src/events/message-create/index.ts (2)
61-62
: Correct implementation for selfbot context.
The bot filtering logic correctly:
- Filters out bot messages on line 61
- Prevents self-replies by checking against client user ID on line 62
This is the appropriate approach for a selfbot implementation.
31-58
: Well-structured memory storage implementation.
The onSuccess
function properly:
- Fetches recent conversation context (5 messages)
- Formats messages for storage
- Includes comprehensive metadata for both DM and guild contexts
- Handles async operations correctly
src/utils/messages.ts (1)
33-57
: Previous issue resolved: Function now correctly returns processed attachments.
The function properly:
- Filters valid image attachments
- Logs warnings for invalid attachments
- Returns ImagePart array with URLs and media types
The previous issue of returning an empty array has been fixed.
src/lib/pinecone/queries.ts (5)
71-76
: Good practice: Updating retrieval timestamps
Excellent implementation of updating lastRetrievalTime
for retrieved memories. This enables tracking memory usage patterns.
85-124
: Well-implemented search function with proper validation
The function correctly handles embedding generation, querying, and result validation. The use of flatMap
to filter out invalid metadata is a clean pattern.
132-132
: Consider the implications of using MD5 hash as ID
Using MD5 hash of the text as ID means identical texts will share the same ID, potentially overwriting previous entries with different metadata. If this is intentional for deduplication, document it clearly. Otherwise, consider including metadata in the hash or using a UUID.
- const id = new MD5().update(text).digest('hex');
+ // Using MD5 ensures deduplication - same text always gets same ID
+ const id = new MD5().update(text).digest('hex');
Or if deduplication is not desired:
- const id = new MD5().update(text).digest('hex');
+ const id = new MD5().update(text + JSON.stringify(metadata)).digest('hex');
168-180
: Clean implementation of memory deletion
Simple and effective implementation with proper error handling.
37-46
: Fix filter construction bug when both ignoreRecent and ageLimit are set
When both ignoreRecent
and ageLimit
are provided, the current implementation overwrites the $lt
constraint set by ignoreRecent
. This will cause the ignoreRecent filter to be ignored.
if (ignoreRecent) {
filter.createdAt = { $lt: now - 60_000 };
}
if (ageLimit != null) {
- filter.createdAt = {
- ...filter.createdAt,
- $gt: now - ageLimit,
- };
+ filter.createdAt = {
+ ...(filter.createdAt || {}),
+ $gt: now - ageLimit,
+ };
}
Likely an incorrect or invalid review comment.
"rerankinig", | ||
"textembbeding", | ||
"lefthook" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix typos in custom dictionary entries
rerankinig
and textembbeding
are misspelled, defeating the purpose of adding them to the spell-checker dictionary.
- "rerankinig",
- "textembbeding",
+ "reranking",
+ "textembedding",
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
"rerankinig", | |
"textembbeding", | |
"lefthook" | |
"reranking", | |
"textembedding", | |
"lefthook" |
🤖 Prompt for AI Agents
In the .cspell.json file around lines 40 to 42, correct the typos in the custom
dictionary entries by changing "rerankinig" to "reranking" and "textembbeding"
to "textembedding" to ensure these terms are recognized correctly by the
spell-checker.
# use the official Bun image | ||
# see all versions at https://hub.docker.com/r/oven/bun/tags | ||
FROM oven/bun:1 AS base | ||
WORKDIR /usr/src/app | ||
|
||
RUN apt update | ||
|
||
RUN apt install -y \ | ||
curl \ | ||
git \ | ||
sudo \ | ||
python3 \ | ||
python3-pip \ | ||
make | ||
|
||
# install dependencies into temp directory | ||
# this will cache them and speed up future builds | ||
FROM base AS install | ||
RUN mkdir -p /temp/dev | ||
COPY package.json bun.lock /temp/dev/ | ||
RUN cd /temp/dev && bun install --frozen-lockfile | ||
|
||
# install with --production (exclude devDependencies) | ||
RUN mkdir -p /temp/prod | ||
COPY package.json bun.lock /temp/prod/ | ||
RUN cd /temp/prod && bun install --production --ignore-scripts --frozen-lockfile | ||
|
||
# copy node_modules from temp directory | ||
# then copy all (non-ignored) project files into the image | ||
FROM base AS prerelease | ||
COPY --from=install /temp/dev/node_modules node_modules | ||
COPY . . | ||
|
||
# [optional] tests & build | ||
ENV NODE_ENV=production | ||
|
||
# copy production dependencies and source code into final image | ||
FROM base AS release | ||
COPY --from=install /temp/prod/node_modules node_modules | ||
COPY --from=prerelease /usr/src/app . | ||
RUN mkdir -p logs \ | ||
&& chmod 0777 logs | ||
|
||
# run the app | ||
USER bun | ||
ENTRYPOINT [ "bun", "run", "start" ] No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Consider adding HEALTHCHECK for better container monitoring.
Adding a HEALTHCHECK instruction would improve container orchestration and monitoring capabilities.
# run the app
USER bun
+HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
+ CMD curl -f http://localhost:${PORT:-3000}/health || exit 1
ENTRYPOINT [ "bun", "run", "start" ]
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
# use the official Bun image | |
# see all versions at https://hub.docker.com/r/oven/bun/tags | |
FROM oven/bun:1 AS base | |
WORKDIR /usr/src/app | |
RUN apt update | |
RUN apt install -y \ | |
curl \ | |
git \ | |
sudo \ | |
python3 \ | |
python3-pip \ | |
make | |
# install dependencies into temp directory | |
# this will cache them and speed up future builds | |
FROM base AS install | |
RUN mkdir -p /temp/dev | |
COPY package.json bun.lock /temp/dev/ | |
RUN cd /temp/dev && bun install --frozen-lockfile | |
# install with --production (exclude devDependencies) | |
RUN mkdir -p /temp/prod | |
COPY package.json bun.lock /temp/prod/ | |
RUN cd /temp/prod && bun install --production --ignore-scripts --frozen-lockfile | |
# copy node_modules from temp directory | |
# then copy all (non-ignored) project files into the image | |
FROM base AS prerelease | |
COPY --from=install /temp/dev/node_modules node_modules | |
COPY . . | |
# [optional] tests & build | |
ENV NODE_ENV=production | |
# copy production dependencies and source code into final image | |
FROM base AS release | |
COPY --from=install /temp/prod/node_modules node_modules | |
COPY --from=prerelease /usr/src/app . | |
RUN mkdir -p logs \ | |
&& chmod 0777 logs | |
# run the app | |
USER bun | |
ENTRYPOINT [ "bun", "run", "start" ] | |
# run the app | |
USER bun | |
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ | |
CMD curl -f http://localhost:${PORT:-3000}/health || exit 1 | |
ENTRYPOINT [ "bun", "run", "start" ] |
🧰 Tools
🪛 Checkov (3.2.334)
[LOW] 6-6: Ensure that APT isn't used
(CKV_DOCKER_9)
[LOW] 1-46: Ensure that HEALTHCHECK instructions have been added to container images
(CKV_DOCKER_2)
[LOW] 8-14: Ensure that sudo isn't used
(CKV2_DOCKER_1)
🪛 Hadolint (2.12.0)
[warning] 6-6: Do not use apt as it is meant to be a end-user tool, use apt-get or apt-cache instead
(DL3027)
[info] 8-8: Multiple consecutive RUN
instructions. Consider consolidation.
(DL3059)
[warning] 8-8: Do not use apt as it is meant to be a end-user tool, use apt-get or apt-cache instead
(DL3027)
[warning] 21-21: Use WORKDIR to switch to a directory
(DL3003)
[warning] 26-26: Use WORKDIR to switch to a directory
(DL3003)
🤖 Prompt for AI Agents
In Dockerfile lines 1 to 46, add a HEALTHCHECK instruction to improve container
monitoring. Define a command that periodically tests the app's health, such as
making an HTTP request to a health endpoint or checking a process status, and
specify appropriate intervals and retries. Insert this HEALTHCHECK near the end
of the Dockerfile, before the USER and ENTRYPOINT instructions.
FROM oven/bun:1 AS base | ||
WORKDIR /usr/src/app | ||
|
||
RUN apt update |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use apt-get instead of apt for better reliability.
The apt
command is intended for end-users and may have unstable output. Use apt-get
for scripts and containers.
-RUN apt update
+RUN apt-get update
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
RUN apt update | |
RUN apt-get update |
🧰 Tools
🪛 Checkov (3.2.334)
[LOW] 6-6: Ensure that APT isn't used
(CKV_DOCKER_9)
🪛 Hadolint (2.12.0)
[warning] 6-6: Do not use apt as it is meant to be a end-user tool, use apt-get or apt-cache instead
(DL3027)
🤖 Prompt for AI Agents
In Dockerfile at line 6, replace the command 'apt update' with 'apt-get update'
to ensure better reliability and stability in the container build process, as
'apt-get' is more suitable for scripting and automation than 'apt'.
RUN apt install -y \ | ||
curl \ | ||
git \ | ||
sudo \ | ||
python3 \ | ||
python3-pip \ | ||
make |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider security and consolidation improvements.
Multiple issues:
- Use
apt-get
instead ofapt
- Consider if
sudo
is necessary in a container - Consolidate RUN instructions for better layer caching
-RUN apt install -y \
+RUN apt-get update && apt-get install -y \
curl \
git \
- sudo \
python3 \
python3-pip \
- make
+ make \
+ && rm -rf /var/lib/apt/lists/*
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
RUN apt install -y \ | |
curl \ | |
git \ | |
sudo \ | |
python3 \ | |
python3-pip \ | |
make | |
RUN apt-get update && apt-get install -y \ | |
curl \ | |
git \ | |
python3 \ | |
python3-pip \ | |
make \ | |
&& rm -rf /var/lib/apt/lists/* |
🧰 Tools
🪛 Checkov (3.2.334)
[LOW] 8-14: Ensure that sudo isn't used
(CKV2_DOCKER_1)
🪛 Hadolint (2.12.0)
[info] 8-8: Multiple consecutive RUN
instructions. Consider consolidation.
(DL3059)
[warning] 8-8: Do not use apt as it is meant to be a end-user tool, use apt-get or apt-cache instead
(DL3027)
🤖 Prompt for AI Agents
In Dockerfile lines 8 to 14, replace `apt install` with `apt-get install` for
better compatibility and scripting reliability. Evaluate if `sudo` is needed
inside the container; if not, remove it to reduce image size and security risks.
Also, consolidate all package installation commands into a single RUN
instruction to optimize layer caching and reduce image layers.
FROM base AS install | ||
RUN mkdir -p /temp/dev | ||
COPY package.json bun.lock /temp/dev/ | ||
RUN cd /temp/dev && bun install --frozen-lockfile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Use WORKDIR instead of cd for clarity.
Using WORKDIR
is more explicit and clearer than changing directories with cd
.
-RUN cd /temp/dev && bun install --frozen-lockfile
+WORKDIR /temp/dev
+RUN bun install --frozen-lockfile
Apply similar pattern for line 26.
Also applies to: 26-26
🧰 Tools
🪛 Hadolint (2.12.0)
[warning] 21-21: Use WORKDIR to switch to a directory
(DL3003)
🤖 Prompt for AI Agents
In Dockerfile at lines 21 and 26, replace the use of `cd` commands with
`WORKDIR` instructions to set the working directory explicitly before running
commands. This improves clarity and Docker layer caching. Set `WORKDIR
/temp/dev` before the `bun install --frozen-lockfile` command on line 21, and
similarly set the appropriate `WORKDIR` before the command on line 26.
export async function convertToModelMessages( | ||
messages: Collection<string, DiscordMessage<boolean>> | ||
): Promise<Array<ModelMessage>> { | ||
return await Promise.all( | ||
messages.map(async (msg) => { | ||
const ref = msg.reference | ||
? await msg.fetchReference().catch(() => null) | ||
: null; | ||
const text = ref | ||
? `${msg.author.username}: ${msg.content}` | ||
: `${msg.author.username}: ${msg.content}`; | ||
|
||
return { | ||
role: msg.author.id === msg.client.user?.id ? 'assistant' : 'user', | ||
content: [ | ||
{ type: 'text' as const, text }, | ||
...(await processAttachments(msg.attachments)), | ||
], | ||
createdAt: msg.createdAt, | ||
}; | ||
}) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Fix TypeScript role type error
The pipeline failure indicates a type mismatch in the role property. The current implementation returns 'user' | 'assistant'
but TypeScript expects a different type.
🏁 Script executed:
#!/bin/bash
# Check the ModelMessage type definition to understand the expected role type
ast-grep --pattern 'type ModelMessage = {
$$$
}'
# Also check for interface definition
ast-grep --pattern 'interface ModelMessage {
$$$
}'
# Search for ModelMessage type in ai module types
fd -e ts -e d.ts | xargs rg -A 10 "type ModelMessage|interface ModelMessage"
Length of output: 1047
Confirm ModelMessage.role literal types
To resolve the type mismatch, we need the exact ModelMessage
definition from the ai
package—especially the allowed string literals for the role
property.
🌐 Web query:
What is the TypeScript definition of `ModelMessage` exported by the `ai` npm package? Specifically, which string literal types are allowed for the `role` property?
💡 Result:
In the ai
npm package, the ModelMessage
type defines the structure of messages exchanged with AI models. The role
property within ModelMessage
is a string literal type that can be one of the following values:
'system'
'user'
'assistant'
'tool'
Each of these roles represents a different participant or component in the messaging system:
'system'
: Messages that contain system information.'user'
: Messages originating from the user.'assistant'
: Messages generated by the assistant.'tool'
: Messages that contain the result of one or more tool calls.
This structure allows for clear differentiation between the various types of messages in the system. (v5.ai-sdk.dev)
Citations:
🏁 Script executed:
#!/bin/bash
# Display the imports and signature of convertToModelMessages to verify ModelMessage source and role typing
sed -n '1,20p' src/utils/messages.ts
Length of output: 707
Remove unsupported createdAt
property from ModelMessage
The ModelMessage
type imported from ai
defines only role
, content
, and an optional name
. The extra createdAt
field in your returned object isn’t part of that definition and is causing the TypeScript error.
• File: src/utils/messages.ts
, function convertToModelMessages
– Remove the createdAt: msg.createdAt
line from the returned object.
Suggested diff:
export async function convertToModelMessages(
messages: Collection<string, DiscordMessage<boolean>>
): Promise<Array<ModelMessage>> {
return await Promise.all(
messages.map(async (msg) => {
const ref = msg.reference
? await msg.fetchReference().catch(() => null)
: null;
const text = `${msg.author.username}: ${msg.content}`;
return {
role: msg.author.id === msg.client.user?.id ? 'assistant' : 'user',
content: [
{ type: 'text' as const, text },
...(await processAttachments(msg.attachments)),
],
- createdAt: msg.createdAt,
};
})
);
}
If you still need to track timestamps, consider defining a wrapper type (for example, type TimestampedMessage = ModelMessage & { createdAt: Date }
) and handling it outside of the AI-model payload.
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 GitHub Actions: CI
[error] 12-12: TypeScript error TS2322: Type '{ role: "user" | "assistant"; content: (ImagePart | { type: "text"; text: string; })[]; createdAt: Date; }[]' is not assignable to type 'ModelMessage[]'. Role property type mismatch between 'user' | 'assistant' and expected 'assistant'.
🤖 Prompt for AI Agents
In src/utils/messages.ts around lines 9 to 30, the returned object in
convertToModelMessages includes a createdAt property which is not defined in the
ModelMessage type and causes a TypeScript error. Remove the createdAt:
msg.createdAt line from the returned object to match the ModelMessage type
definition. If you need to track timestamps, handle them separately outside the
AI-model payload.
? await msg.fetchReference().catch(() => null) | ||
: null; | ||
const text = ref | ||
? `${msg.author.username}: ${msg.content}` | ||
: `${msg.author.username}: ${msg.content}`; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Remove unused message reference fetch
The code fetches a message reference but doesn't use it in the text formatting. Both branches of the ternary operator produce identical output.
Either remove the reference fetch:
- const ref = msg.reference
- ? await msg.fetchReference().catch(() => null)
- : null;
- const text = ref
- ? `${msg.author.username}: ${msg.content}`
- : `${msg.author.username}: ${msg.content}`;
+ const text = `${msg.author.username}: ${msg.content}`;
Or include reference context in the formatting:
const text = ref
- ? `${msg.author.username}: ${msg.content}`
+ ? `${msg.author.username} (replying to ${ref.author.username}): ${msg.content}`
: `${msg.author.username}: ${msg.content}`;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const ref = msg.reference | |
? await msg.fetchReference().catch(() => null) | |
: null; | |
const text = ref | |
? `${msg.author.username}: ${msg.content}` | |
: `${msg.author.username}: ${msg.content}`; | |
const text = `${msg.author.username}: ${msg.content}`; |
🤖 Prompt for AI Agents
In src/utils/messages.ts around lines 14 to 19, the code fetches a message
reference but does not use it in the text formatting, resulting in identical
output for both branches of the ternary operator. To fix this, either remove the
fetchReference call and the related conditional logic entirely, or modify the
text formatting to include information from the fetched reference when it
exists, so the reference fetch serves a purpose.
systemPrompt({ | ||
selectedChatModel: 'chat-model', | ||
}) + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix missing required property 'requestHints'
The systemPrompt
function requires both selectedChatModel
and requestHints
parameters, but only selectedChatModel
is provided. This causes a TypeScript compilation error.
- system:
- systemPrompt({
- selectedChatModel: 'chat-model',
- }) +
+ system:
+ systemPrompt({
+ selectedChatModel: 'chat-model',
+ requestHints: {},
+ }) +
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
systemPrompt({ | |
selectedChatModel: 'chat-model', | |
}) + | |
system: | |
systemPrompt({ | |
selectedChatModel: 'chat-model', | |
requestHints: {}, | |
}) + |
🧰 Tools
🪛 GitHub Actions: CI
[error] 11-11: TypeScript error TS2345: Argument of type '{ selectedChatModel: string; }' is not assignable to parameter of type '{ selectedChatModel: string; requestHints: RequestHints; }'. Missing required property 'requestHints'.
🤖 Prompt for AI Agents
In src/utils/voice/helpers/ai.ts around lines 11 to 13, the call to systemPrompt
is missing the required property 'requestHints'. Update the systemPrompt call to
include both 'selectedChatModel' and 'requestHints' properties with appropriate
values to satisfy the function's parameter requirements and fix the TypeScript
error.
Implement Conversation history for Voice Chat, previous message memory + chat history. | ||
Add Commit Lint to enforce strict commit messages, and add lint pipelines. | ||
Allow People to Customize Zenix's Speed, and other settings in a /config command (per-server). | ||
Refactor the channels command to be more easy to use, with deny and allow lists. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Improve phrasing: "more easy" → "easier".
The phrase "more easy" sounds awkward and informal.
- Refactor the channels command to be more easy to use, with deny and allow lists.
+ Refactor the channels command to be easier to use, with deny and allow lists.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
Refactor the channels command to be more easy to use, with deny and allow lists. | |
Refactor the channels command to be easier to use, with deny and allow lists. |
🧰 Tools
🪛 LanguageTool
[style] ~13-~13: The phrasing ‘more easy’ can sound awkward and informal. Consider using a comparative adjective or other alternative.
Context: ...).
Refactor the channels command to be more easy to use, with deny and allow lists.
D...
(MORE_EASY_N_CLEAR)
🤖 Prompt for AI Agents
In TODO.md at line 13, replace the phrase "more easy" with the grammatically
correct and more natural word "easier" to improve the phrasing of the comment
about refactoring the channels command.
|
||
Refactor the ping system, the bot pings random people and doesn't know who is who | ||
Add edit delete messages functionality for gork, meaning it can understand when messages were edited and also edit it's own messages liek Frank | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix typo: "liek" should be "like".
The pipeline failure detected this spelling error.
- Add edit delete messages functionality for gork, meaning it can understand when messages were edited and also edit it's own messages liek Frank
+ Add edit delete messages functionality for gork, meaning it can understand when messages were edited and also edit its own messages like Frank
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
Add edit delete messages functionality for gork, meaning it can understand when messages were edited and also edit it's own messages liek Frank | |
Add edit delete messages functionality for gork, meaning it can understand when messages were edited and also edit its own messages like Frank |
🧰 Tools
🪛 GitHub Actions: CI
[error] 55-55: cspell: Unknown word 'liek' detected; suggested fix: 'like'.
🤖 Prompt for AI Agents
In TODO.md at line 55, correct the typo "liek" to "like" in the sentence
describing the edit and delete messages functionality for gork to fix the
spelling error causing the pipeline failure.
Description
Type of Change
Pre-flight Checklist
bun check
without any issuesAdditional Notes
Summary by CodeRabbit
New Features
Improvements
discord.js
todiscord.js-selfbot-v13
for Discord interactions.Bug Fixes
Documentation
Chores