-
Notifications
You must be signed in to change notification settings - Fork 5
feat: Add chat command for AI interaction and enhance message handlin… #16
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
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
WalkthroughThis update introduces a web search feature using ExaAI, adds a new slash command for chat, and integrates a web search tool into the AI assistant. The changes include new and updated environment variables, configuration files, stricter linting and commit message standards, expanded prompts, improved type safety, and refactored tool and context handling. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DiscordBot
participant ExaAI
participant AI_Assistant
User->>DiscordBot: Uses /chat slash command with prompt
DiscordBot->>AI_Assistant: Builds context (with MinimalContext)
AI_Assistant->>ExaAI: (If needed) Calls searchWeb tool with query
ExaAI-->>AI_Assistant: Returns web search results
AI_Assistant-->>DiscordBot: Generates reply (may include search results)
DiscordBot-->>User: Sends response message
Possibly related PRs
Poem
✨ 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: 26
🔭 Outside diff range comments (5)
src/utils/time.ts (1)
1-10:TZDateis a type, not a runtime constructor – this will crash at runtime
@date-fns/tzexportsTZDateonly as a TypeScript type alias.
new TZDate()fails because no value with that name exists at runtime.-import { TZDate } from '@date-fns/tz'; -import { format } from 'date-fns'; +import { formatInTimeZone } from 'date-fns-tz';export function getTimeInCity( timezone: string, formatStr = 'yyyy-MM-dd HH:mm:ssXXX', ): string { - const now = new Date(); - const zonedDate = new TZDate(now, timezone); - return format(zonedDate, formatStr); + return formatInTimeZone(new Date(), timezone, formatStr); }This removes the invalid constructor call while keeping the same public API.
src/index.ts (1)
41-50: Unhandled promise & suppressed type errors
commands[commandName …].execute(interaction);is async but not awaited and errors will bubble to the global handler, potentially crashing the bot.Coupled with the
// @ts-expect-error, you’re actively hiding a structural typing issue.-client.on(Events.InteractionCreate, async (interaction) => { +client.on(Events.InteractionCreate, async (interaction) => { if (!interaction.isCommand()) { return; } const { commandName } = interaction; - if (commands[commandName as keyof typeof commands]) { - // @ts-expect-error todo: fix this - commands[commandName as keyof typeof commands].execute(interaction); + const command = commands[commandName as keyof typeof commands]; + if (command) { + try { + await command.execute(interaction); + } catch (error) { + logger.error(error, `Failed to execute /${commandName}`); + if (interaction.replied || interaction.deferred) { + await interaction.followUp({ content: 'Something went wrong!', ephemeral: true }); + } else { + await interaction.reply({ content: 'Something went wrong!', ephemeral: true }); + } + } } });This removes the suppression, awaits the promise, and surfaces controlled feedback to users.
src/utils/voice/stream.ts (1)
50-62:playAudiois async but not awaitedYou now correctly
await speak, butplayAudiolikely returns a promise (stream piping / player subscription). Not awaiting it may resume transcription early and overlap audio.- // @ts-expect-error this is a ReadableStream - playAudio(player, audio); + // @ts-expect-error playAudio returns a promise we intentionally await + await playAudio(player, audio);Also consider resuming
playerviaplayer.unpause()after playback if simultaneous transcription is desired.src/commands/voice-channel/join.ts (2)
45-49: Potential listener leak onreceiver.speakingEvery execution adds a permanent
speakinglistener. Re-invoking /join (or simply reloading the bot) will accumulate listeners and duplicate audio processing.- receiver.speaking.on('start', async (userId) => { + const onSpeaking = async (userId: string) => { const user = await interaction.client.users.fetch(userId); await createListeningStream(receiver, player, user); - }); + }; + receiver.speaking.once('start', onSpeaking); + connection.once(VoiceConnectionStatus.Destroyed, () => + receiver.speaking.off('start', onSpeaking), + );
18-20: PrefereditReply()over the firstfollowUp()afterdeferReply()
interaction.deferReply()reserves the initial response. Usinginteraction.editReply()keeps the interaction thread clean and avoids exceeding Discord’s 5-message per-interaction hard limit.- await interaction.deferReply(); + await interaction.deferReply(); ... - await interaction.followUp( + await interaction.editReply( "oops, idk what happened. I couldn't join the voice channel.", ); ... - await interaction.followUp('thanks for inviting me! joined'); + await interaction.editReply('thanks for inviting me! joined');Also applies to: 52-58
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (46)
.cspell.json(1 hunks).env.example(1 hunks).eslintignore(1 hunks).eslintrc.json(1 hunks).github/CODEOWNERS(1 hunks).github/FUNDING.yml(1 hunks).github/pull-request-template.md(1 hunks).husky/commit-msg(1 hunks).husky/pre-commit(1 hunks).vscode/settings.json(0 hunks)TODO.md(1 hunks)commitlint.config.ts(1 hunks)package.json(3 hunks)src/commands/channels.ts(1 hunks)src/commands/chat.ts(1 hunks)src/commands/index.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(3 hunks)src/config.ts(2 hunks)src/deploy-commands.ts(1 hunks)src/env.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(2 hunks)src/index.ts(1 hunks)src/lib/ai/prompts.ts(3 hunks)src/lib/ai/providers.ts(1 hunks)src/lib/ai/tools/discord.ts(3 hunks)src/lib/ai/tools/report.ts(1 hunks)src/lib/ai/tools/search-web.ts(1 hunks)src/lib/logger.ts(1 hunks)src/lib/queries.ts(0 hunks)src/lib/search.ts(1 hunks)src/utils/context.ts(1 hunks)src/utils/delay.ts(2 hunks)src/utils/discord.ts(1 hunks)src/utils/message-rate-limiter.ts(1 hunks)src/utils/messages.ts(2 hunks)src/utils/sandbox.ts(4 hunks)src/utils/status.ts(2 hunks)src/utils/time.ts(1 hunks)src/utils/voice/helpers/ai.ts(1 hunks)src/utils/voice/helpers/audio.ts(1 hunks)src/utils/voice/helpers/index.ts(1 hunks)src/utils/voice/stream.ts(2 hunks)
💤 Files with no reviewable changes (2)
- src/lib/queries.ts
- .vscode/settings.json
🧰 Additional context used
🧬 Code Graph Analysis (7)
src/lib/search.ts (1)
src/env.ts (1)
env(4-58)
src/utils/context.ts (1)
src/utils/messages.ts (1)
MinimalContext(10-13)
src/utils/voice/stream.ts (2)
src/utils/voice/helpers/deepgram.ts (1)
speak(11-23)src/config.ts (1)
voice(37-39)
src/lib/ai/tools/report.ts (1)
src/utils/messages.ts (1)
MinimalContext(10-13)
src/utils/status.ts (1)
src/config.ts (1)
activities(16-21)
src/lib/ai/tools/search-web.ts (1)
src/lib/search.ts (1)
exa(10-10)
src/events/message-create/utils/respond.ts (4)
src/utils/messages.ts (2)
MinimalContext(10-13)isDiscordMessage(67-69)src/lib/ai/prompts.ts (1)
RequestHints(3-12)src/lib/ai/tools/report.ts (1)
report(6-34)src/lib/ai/tools/discord.ts (1)
discord(17-166)
🪛 ESLint
src/lib/ai/tools/discord.ts
[error] 6-6: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 8-8: Unable to resolve path to module 'zod/v4'.
(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/index.ts
[error] 10-10: Unable to resolve path to module 'discord.js'.
(import-x/no-unresolved)
src/lib/search.ts
[error] 2-2: Unable to resolve path to module 'exa-js'.
(import-x/no-unresolved)
src/deploy-commands.ts
[error] 2-2: Unable to resolve path to module 'discord.js'.
(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/utils/context.ts
[error] 6-6: Unable to resolve path to module '@mem0/vercel-ai-provider'.
(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/commands/voice-channel/index.ts
[error] 1-1: Unable to resolve path to module 'discord.js'.
(import-x/no-unresolved)
src/utils/delay.ts
[error] 3-3: Unable to resolve path to module 'discord.js'.
(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/time.ts
[error] 2-2: Unable to resolve path to module 'date-fns'.
(import-x/no-unresolved)
src/utils/messages.ts
[error] 8-8: Unable to resolve path to module 'discord.js'.
(import-x/no-unresolved)
src/lib/logger.ts
[error] 5-5: Unable to resolve path to module 'pino'.
(import-x/no-unresolved)
src/lib/ai/providers.ts
[error] 1-1: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
[error] 3-3: Unable to resolve path to module '@ai-sdk/openai'.
(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)
src/commands/voice-channel/leave.ts
[error] 1-1: Unable to resolve path to module '@discordjs/voice'.
(import-x/no-unresolved)
src/utils/status.ts
[error] 4-4: Unable to resolve path to module 'discord.js'.
(import-x/no-unresolved)
src/commands/chat.ts
[error] 8-8: Unable to resolve path to module 'discord.js'.
(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/events/message-create/utils/respond.ts
[error] 9-9: Unable to resolve path to module '@mem0/vercel-ai-provider'.
(import-x/no-unresolved)
[error] 11-11: Unable to resolve path to module 'ai'.
(import-x/no-unresolved)
src/index.ts
[error] 7-7: Unable to resolve path to module 'discord.js'.
(import-x/no-unresolved)
🪛 dotenv-linter (3.3.0)
.env.example
[warning] 60-60: [EndingBlankLine] No blank line at the end of the file
🪛 LanguageTool
.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-breaki...
(FIX_RESOLVE)
TODO.md
[uncategorized] ~9-~9: Did you mean “its” (the possessive pronoun)?
Context: ...realistic. Separate Deepgram code into it's files Implement Conversation history fo...
(ITS_PREMIUM)
[style] ~13-~13: The phrasing ‘more easy’ can sound awkward and informal. Consider using a comparative adjective or other alternative.
Context: ...r). Refactor the channels command to be more easy to use, with deny and allow lists. Det...
(MORE_EASY_N_CLEAR)
[typographical] ~15-~15: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...he response before replying fully, wait 1-2 seconds (for one user). This adds dedup...
(HYPHEN_TO_EN)
[uncategorized] ~23-~23: A comma might be missing here.
Context: ...pGram things are kept When the user is typing increase the response speed by 0.5x. Al...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~23-~23: A comma might be missing here.
Context: ... 0.5x. Also, use a different method for responding like a set WPM. Add CI/CD testing so p...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~25-~25: This verb does not appear to agree with the subject. Consider using a different form.
Context: ...testing so pushing things to production don't break stuff. Add context to when th...
(AI_EN_LECTOR_REPLACEMENT_VERB_AGREEMENT)
[typographical] ~33-~33: Consider adding a comma here.
Context: ...the bot always remembers the same person no matter where they interact with it.
(NO_MATTER_COMMA)
🪛 markdownlint-cli2 (0.17.2)
.github/pull-request-template.md
1-1: First line in a file should be a top-level heading
null
(MD041, first-line-heading, first-line-h1)
🪛 Biome (1.9.4)
src/commands/chat.ts
[error] 36-36: Forbidden non-null assertion.
(lint/style/noNonNullAssertion)
🔇 Additional comments (30)
.eslintignore (1)
2-2: ```shell
#!/bin/bash
cat -n .eslintignore</details> <details> <summary>src/lib/logger.ts (1)</summary> `2-5`: ```shell #!/bin/bash # Check if 'pino' is listed in dependencies or devDependencies in package.json grep -R '"pino"' -n package.json || truesrc/commands/voice-channel/index.ts (1)
1-1: Import reorder is purely stylistic
Swapping the twodiscord.jsimports has no functional impact.src/utils/voice/helpers/index.ts (1)
2-2: Export order change has no side effects
Moving theaudioexport afteraiis safe and does not affect module resolution.src/utils/message-rate-limiter.ts (1)
2-2: Import statement reordering is acceptable
ReorderingredisandredisKeysbelowmessageThresholdaligns with the project's import grouping convention.src/utils/voice/helpers/ai.ts (1)
2-3: Maintain import consistency and verify 'ai' resolution
Switching the order ofmyProviderandgenerateTextis safe. Please confirm that theaipackage is installed and correctly configured in yourpackage.json/tsconfig.json.src/events/message-create/utils/relevance.ts (1)
4-5: Import reorder is fine; check 'ai' module path
SwappinggenerateObject, ModelMessageand the DiscordMessageimport doesn't affect behavior. Ensure theaimodule exists in dependencies and that TypeScript can resolve its types.src/deploy-commands.ts (1)
2-2: ES Lint is flagging an unresolveddiscord.jspath – double-check your module resolution configESLint’s
import-x/no-unresolvedhint suggests the resolver cannot locatediscord.js.
If you’re on ESM + TS with path aliases, ensure:
typescriptpaths +ts-node/bundler config mapdiscord.jscorrectly.eslint-import-resolver-typescript(or Node) is enabled and sees yourtsconfig.json.This avoids false-positive CI failures.
src/utils/discord.ts (1)
72-75: Good move: switching parameter type fromanytounknowntightens type safetyThe new signature protects callers from accidentally bypassing type checks while retaining the same runtime behaviour.
No further action needed..github/FUNDING.yml (1)
1-2: Funding file looks correctGitHub Sponsors and Buy Me a Coffee entries are properly formatted.
src/index.ts (1)
1-10:discord.jspath resolution fails under ESLintESLint reports
import-x/no-unresolvedfor'discord.js'.
If you rely on path aliases (@/…) viatsconfig/eslint-import-resolver-typescript, ensure the resolver also treats bare packages, or pin a type-only import (import type) when running in Bun/Deno environments.Run the resolver to confirm all bare package imports are recognised:
#!/bin/bash # List unresolved imports reported by ESLint eslint --ext .ts src | grep "no-unresolved"src/events/message-create/index.ts (1)
2-16: Broken module resolution fordiscord.js& KV libsESLint flags
import-x/no-unresolvedfor'discord.js'. Verify that yourpaths/moduleResolutionintsconfig.jsonand the ESLint import resolver are aligned; otherwise CI will keep failing.If the issue is false-positive (e.g., monorepo hoisting), add the correct resolver config instead of silencing the rule.
src/utils/voice/stream.ts (1)
1-12: Resolve missing peer dependencies
@deepgram/sdk,@discordjs/voice, andprism-mediaare flagged as unresolved. Ensure they are listed inpackage.jsondependencies, not just devDependencies, or production deployments will break.src/commands/channels.ts (1)
1-8: Import shuffle looks fine.Pure re-ordering; no functional or build impact detected.
src/utils/delay.ts (1)
51-53: Removal of.toLowerCase()might break downstream text-matching logic.Several NLP / regex routines elsewhere may have assumed lower-cased segments (e.g. keyword filters or similarity checks). Verify that preserving the original casing in
textdoes not impact those call-sites.src/lib/ai/tools/report.ts (1)
1-7: Unresolvable module paths – update imports.ESLint flags both
aiandzod/v4as unknown. Unless you have path aliases for them, change to the canonical packages:-import { tool } from 'ai'; -import { z } from 'zod/v4'; +import { tool } from 'ai-js'; // or your actual helper library +import { z } from 'zod';Confirm that the build & type-checker run cleanly after adjusting.
src/commands/voice-channel/join.ts (1)
11-13: ```shell
#!/bin/bashShow src/commands/voice-channel/index.ts to inspect how commands are aggregated
echo "🔍 src/commands/voice-channel/index.ts (first 200 lines):"
sed -n '1,200p' src/commands/voice-channel/index.ts || echo "⚠️ File not found: src/commands/voice-channel/index.ts"echo
Show root commands index if exists
echo "🔍 src/commands/index.ts (first 200 lines):"
sed -n '1,200p' src/commands/index.ts || echo "⚠️ File not found: src/commands/index.ts"</details> <details> <summary>src/config.ts (2)</summary> `12-13`: **Tripling `speedFactor` changes response pacing – validate UX** Raising `speedFactor` from 60 → 180 will cut the typing-simulation delay to one-third (because delay = tokens / speedFactor under the “divide” strategy). Please confirm this does not make replies appear “too instantaneous” and bot-like, especially for long outputs. --- `24-35`: **`as const` annotation is spot-on – nice type-safety improvement** Explicit literal roles eliminate accidental widening to `string`, which helps downstream discriminated unions. </details> <details> <summary>src/lib/ai/tools/discord.ts (2)</summary> `55-60`: **Good move: tighten `sharedState` to `unknown`** Using `unknown` forces explicit type-narrowing inside sandboxed code and reduces accidental leakage of unsafe `any`. 👍 --- `1-10`: ```shell #!/bin/bash # Inspect package.json for 'ai' and 'zod' dependencies echo "=== dependencies in package.json ===" grep -R "\"dependencies\"" -n package.json -A 20 || true echo echo "=== devDependencies in package.json ===" grep -R "\"devDependencies\"" -n package.json -A 20 || true echo echo "=== Look for 'ai' and 'zod' in package.json ===" grep -R "\"ai\"" -n package.json || true grep -R "\"zod\"" -n package.json || true echo # Check TS config for path mappings and baseUrl echo "=== tsconfig.json paths and baseUrl ===" grep -R "\"paths\"" -n tsconfig.json -A 10 || true grep -R "\"baseUrl\"" -n tsconfig.json -A 5 || truesrc/env.ts (1)
26-35:z.url()is cleaner, but check CI for any string-only usesMigrating
UPSTASH_REDIS_REST_URLtoz.url()will now reject non-URL strings (e.g.,localhost:6379). Ensure all deployment environments provide a fully qualified URL.Addition of mandatory
EXA_API_KEYis fine, but remember to:
- Update secret stores (GitHub Actions, Render, etc.).
- Bump
.env.exampleaccordingly.src/utils/status.ts (1)
38-38: Export order change is fineRe-ordering the named exports has no behavioural impact and matches the call-site order elsewhere in the repo.
src/utils/messages.ts (1)
67-69: Type-guard looks good
instanceof Message && typeof msg.reply === 'function'is sufficient and safe.src/utils/context.ts (1)
1-4: Import re-ordering only – no concernsMoving frequently-used imports to the top improves readability and has no functional impact.
src/lib/ai/providers.ts (1)
22-25: Model identifiers may be invalid (o4-minivsgpt-4o-mini)OpenAI’s official model names use the
gpt-4oprefix. A typo here will surface at runtime with a 404/400 error from the provider.- 'chat-model': openai.responses('gpt-4.1-mini'), - 'reasoning-model': openai.responses('o4-mini'), - 'artifact-model': openai.responses('gpt-4.1'), - 'relevance-model': openai.responses('gpt-4.1-nano'), + // double-check actual model slugs with the provider before merge + 'chat-model': openai.responses('gpt-4o-mini'), + 'reasoning-model': openai.responses('gpt-4o-mini'), + 'artifact-model': openai.responses('gpt-4o'), + 'relevance-model': openai.responses('gpt-4o-nano'),Please verify against the latest OpenAI docs or provider helper.
src/lib/ai/tools/search-web.ts (1)
1-4: Verify import paths to avoid bundler/runtime resolution issues
aiandzod/v4are reported as unresolved by ESLint.
•ai– make sure the package is installed and correctly aliased in your build config.
•zod/v4– the canonical import is usually justzod; the sub-path may break on some bundlers (e.g. ts-node, jest).Confirm these paths resolve in all target environments.
src/commands/voice-channel/leave.ts (1)
4-7: Commenting out thedataobject disables slash-command registrationWith these lines commented, the command loader will skip
leave, meaning users cannot invoke it via/leave. If that’s intentional, consider removing the file or adding adeprecatednotice; otherwise, restore the builder.src/utils/sandbox.ts (1)
18-19: Type-safety & error-handling improvements look goodChanging
any→unknown, refining the error extraction, and keepingAsyncFunctioncreation lint-clean are all solid upgrades.Also applies to: 32-34, 44-48
src/events/message-create/utils/respond.ts (1)
9-11: ESLint “import-x/no-unresolved” warning likely indicates a path-mapping gap
@mem0/vercel-ai-provideris present in package.json but the ESLint resolver can’t locate it, producing noise on every lint.
Either:
- add it to
typescript.tsconfig.paths/moduleResolution, or- in
.eslintrc.jsonconfiguresettings.import/resolverwithnode, or- pin an explicit
exportsfield in the lib (if it’s your package fork).Without fixing this,
bun lint(which is run with--max-warnings 0) will always fail CI.
| @@ -0,0 +1 @@ | |||
| export default { extends: ['@commitlint/config-conventional'] }; | |||
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.
TypeScript config is not loaded by commitlint out-of-the-box
@commitlint/cli expects a plain JS/JSON/YAML config. With the current .ts file, commitlint invoked from the Husky hook will fail to parse the file unless you preload ts-node or run bun commitlint (which transpiles TS).
Two quick fixes:
-// commitlint.config.ts
-export default { extends: ['@commitlint/config-conventional'] };
+// commitlint.config.cjs
+module.exports = { extends: ['@commitlint/config-conventional'] };or keep the TS file but add:
npm i -D ts-node
echo 'require("ts-node").register();' > commitlint.ts-node.js
# and invoke: commitlint --config commitlint.ts-node.js🤖 Prompt for AI Agents
In commitlint.config.ts at line 1, the TypeScript config file is not supported
by commitlint CLI by default, causing parsing failures in Husky hooks. To fix
this, either rename the config file to a supported format like
commitlint.config.js with equivalent JS syntax, or keep the TS file but install
ts-node as a dev dependency and create a JS loader file that requires
ts-node/register, then update the commitlint command to use this loader file as
the config.
| DEEPGRAM_API_KEY=your_deepgram_api_key_here | ||
| ELEVENLABS_API_KEY=your_elevenlabs_api_key_here | ||
| ELEVENLABS_API_KEY=your_elevenlabs_api_key_here | ||
|
|
||
| # --------------------------------------------------------------------------------------------------------- | ||
| # Search | ||
| # Search the web using ExaAI. | ||
| # @see https://exa.ai/ | ||
| # --------------------------------------------------------------------------------------------------------- | ||
| EXA_API_KEY=your_exa_api_key_here |
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)
🧩 Verification correct
Minor hygiene: add trailing newline and verify var names
• dotenv-linter flags the missing newline at EOF – add one for POSIX compliance.
• Ensure the new keys (ELEVENLABS_API_KEY, EXA_API_KEY) exactly match the identifiers used in src/env.ts; a typo will surface only at runtime.
-EXA_API_KEY=your_exa_api_key_here
+EXA_API_KEY=your_exa_api_key_here
+🏁 Script executed:
#!/bin/bash
# Verify that env keys exist in codebase
rg -n $'ELEVENLABS_API_KEY|EXA_API_KEY' | headLength of output: 223
Minor hygiene: add trailing newline and verify var names
• dotenv-linter flags the missing newline at EOF – add one for POSIX compliance.
• Ensure the new keys (ELEVENLABS_API_KEY, EXA_API_KEY) exactly match the identifiers used in src/env.ts; a typo will surface only at runtime.
-EXA_API_KEY=your_exa_api_key_here
+EXA_API_KEY=your_exa_api_key_here
+#!/bin/bash
# Verify that env keys exist in codebase
rg -n $'ELEVENLABS_API_KEY|EXA_API_KEY' | head🧰 Tools
🪛 dotenv-linter (3.3.0)
[warning] 60-60: [EndingBlankLine] No blank line at the end of the file
🤖 Prompt for AI Agents
In the .env.example file around lines 52 to 60, add a trailing newline at the
end of the file to comply with POSIX standards. Also, verify that the
environment variable names ELEVENLABS_API_KEY and EXA_API_KEY exactly match
those used in src/env.ts to prevent runtime errors due to typos. Use a search
tool like ripgrep to confirm these keys are correctly referenced in the
codebase.
| @@ -0,0 +1 @@ | |||
| bun lint-staged | |||
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
Hard dependency on Bun may break contributor workflow
Not every machine running the repo will have bun installed, causing the pre-commit hook to fail. Consider falling back to npm/pnpm or making the command configurable:
-bun lint-staged
+command -v bun >/dev/null 2>&1 && bun lint-staged || npx lint-staged📝 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.
| bun lint-staged | |
| # .husky/pre-commit | |
| command -v bun >/dev/null 2>&1 && bun lint-staged || npx lint-staged |
🤖 Prompt for AI Agents
In the .husky/pre-commit file at line 1, the pre-commit hook currently runs the
command "bun lint-staged", which assumes Bun is installed on every contributor's
machine. To fix this, modify the script to check if Bun is available and fall
back to npm or pnpm if not, or make the command configurable via an environment
variable or config file. This ensures the pre-commit hook works regardless of
the package manager installed.
| AudioPlayerStatus, | ||
| createAudioResource, | ||
| entersState, |
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)
Comment references a removed import – clean up for clarity
StreamType was removed from the import list, yet the block comment below (lines 14-17) still talks about StreamType.Arbitrary.
Prune or update that comment to prevent confusion for maintainers.
🤖 Prompt for AI Agents
In src/utils/voice/helpers/audio.ts around lines 3 to 5, the import of
StreamType was removed but the block comment on lines 14 to 17 still references
StreamType.Arbitrary. Update or remove that part of the comment to reflect the
current imports and avoid confusion for future maintainers.
| @@ -0,0 +1 @@ | |||
| * @techwithanirudh 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)
Add a trailing newline for POSIX-compliance
Most linters/readers expect text files to end with a \n.
Appending one avoids diff noise the next time the file is edited.
-* @techwithanirudh
+* @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.
| * @techwithanirudh | |
| * @techwithanirudh | |
🤖 Prompt for AI Agents
In .github/CODEOWNERS at line 1, the file lacks a trailing newline character
which is required for POSIX-compliance. Add a newline character at the end of
the file to ensure it ends with a '\n', preventing unnecessary diff noise in
future edits.
| "*.{cjs,mjs,js,jsx,cts,mts,ts,tsx,json}": "eslint --fix .", | ||
| "**/*": [ | ||
| "prettier --write --ignore-unknown", | ||
| "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.
🧹 Nitpick (assertive)
Heavy eslint fix on entire repo per staged commit
"eslint --fix ." runs over the whole codebase for every staged commit, which can take seconds and rewrites unrelated files.
Consider:
"*.{js,ts,tsx}": "eslint --fix"so eslint only processes the staged subset.
🤖 Prompt for AI Agents
In package.json lines 82 to 86, the current lint-staged configuration runs
"eslint --fix ." on the entire codebase for every staged commit, causing slow
performance and rewriting unrelated files. Modify the eslint command to only run
on the staged files by changing the pattern to "*. {js,ts,tsx}" and removing the
"." argument, so eslint only processes the staged subset of files.
| "check": "bun lint && bun typecheck && bun format:check && bun check:spelling", | ||
| "check:spelling": "cspell -c .cspell.json --no-progress --no-summary --no-must-find-files --unique", | ||
| "prepare": "husky" | ||
| }, |
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.
check and lint-staged commands call scripts incorrectly
bun lint / bun check:spelling execute a file called lint (or check:spelling) instead of an npm-style script.
Use bun run (or plain npm run) so the declared scripts are invoked:
- "check": "bun lint && bun typecheck && bun format:check && bun check:spelling",
+ "check": "bun run lint && bun run typecheck && bun run format:check && bun run check:spelling",The same applies inside the lint-staged array:
- "bun check:spelling"
+ "bun run check:spelling"Otherwise pre-commit hooks will fail with “ENOENT: no such file or directory ‘lint’”.
📝 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.
| "check": "bun lint && bun typecheck && bun format:check && bun check:spelling", | |
| "check:spelling": "cspell -c .cspell.json --no-progress --no-summary --no-must-find-files --unique", | |
| "prepare": "husky" | |
| }, | |
| // package.json | |
| { | |
| "scripts": { | |
| // … | |
| - "check": "bun lint && bun typecheck && bun format:check && bun check:spelling", | |
| + "check": "bun run lint && bun run typecheck && bun run format:check && bun run check:spelling", | |
| "check:spelling": "cspell -c .cspell.json --no-progress --no-summary --no-must-find-files --unique", | |
| "prepare": "husky" | |
| }, | |
| // … | |
| "lint-staged": [ | |
| // other entries | |
| - "bun check:spelling" | |
| + "bun run check:spelling" | |
| // other entries | |
| ] | |
| } |
🤖 Prompt for AI Agents
In package.json lines 23 to 26, the scripts "check" and "check:spelling" are
called directly with "bun lint" and "bun check:spelling", which tries to execute
files named "lint" or "check:spelling" instead of running the npm scripts. To
fix this, prefix these commands with "bun run" so they correctly invoke the
npm-style scripts, e.g., use "bun run lint" and "bun run check:spelling". Also,
update any references to these scripts in the lint-staged configuration to use
"bun run" similarly to avoid ENOENT errors during pre-commit hooks.
| Separate Deepgram code into it's files | ||
| Implement Conversation history for Voice Chat, previous message memory + chat history. | ||
| Add Commit Lint to enforce strict commit messages, and add lint pipelines. |
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)
Minor grammar: use possessive “its”
“Separate Deepgram code into it's files”
Should be “its”.
-Separate Deepgram code into it's files
+Separate Deepgram code into its files📝 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.
| Separate Deepgram code into it's files | |
| Implement Conversation history for Voice Chat, previous message memory + chat history. | |
| Add Commit Lint to enforce strict commit messages, and add lint pipelines. | |
| Separate Deepgram code into its files | |
| Implement Conversation history for Voice Chat, previous message memory + chat history. | |
| Add Commit Lint to enforce strict commit messages, and add lint pipelines. |
🧰 Tools
🪛 LanguageTool
[uncategorized] ~9-~9: Did you mean “its” (the possessive pronoun)?
Context: ...realistic. Separate Deepgram code into it's files Implement Conversation history fo...
(ITS_PREMIUM)
🤖 Prompt for AI Agents
In TODO.md around lines 9 to 11, the phrase "Separate Deepgram code into it's
files" uses the incorrect possessive form "it's." Replace "it's" with the
correct possessive pronoun "its" to fix the grammar.
| 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)
Wording nit: “more easy” → “easier”
-Refactor the channels command to be more easy to use
+Refactor the channels command to be easier to use📝 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 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: ...r). Refactor the channels command to be more easy to use, with deny and allow lists. Det...
(MORE_EASY_N_CLEAR)
🤖 Prompt for AI Agents
In TODO.md at line 13, change the phrase "more easy" to the grammatically
correct "easier" to improve wording clarity.
| 3. \`searchWeb\` | ||
| - Use this to search the web for information. | ||
| - You can search for any topic, and it will return relevant results. | ||
| 4. \`getWeather\` | ||
| - Use this to get the current weather for a specific location. | ||
| - You can specify a city or country, and it will return the current weather conditions. | ||
| Use the tools responsibly. Plan ahead. With the \`discord\` tool, **make every call count**. |
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)
Tool order / numbering drift
The prompt now lists searchWeb as item 3 and getWeather as 4 even though getWeather existed first.
Renumber (or switch to unordered bullets) to avoid confusing the LLM’s “you have X tools” mental model.
🤖 Prompt for AI Agents
In src/lib/ai/prompts.ts between lines 76 and 84, the numbered list of tools is
out of order, listing searchWeb as item 3 and getWeather as item 4, even though
getWeather was introduced first. To fix this, renumber the list so that
getWeather appears before searchWeb, or change the list to use unordered bullets
to prevent confusion in the LLM's understanding of tool order.
…g in Discord
Summary by CodeRabbit
New Features
Improvements
Chores
Bug Fixes
Refactor
Style