Skip to content

feat: /tldr conversation summarizer (#25)#105

Merged
BillChirico merged 2 commits intomainfrom
feat/tldr-summarizer
Feb 27, 2026
Merged

feat: /tldr conversation summarizer (#25)#105
BillChirico merged 2 commits intomainfrom
feat/tldr-summarizer

Conversation

@BillChirico
Copy link
Collaborator

Summary

Implements the /tldr slash command — an AI-powered conversation summarizer using Claude Haiku.

What's new

src/commands/tldr.js

  • /tldr — summarize last 50 messages (default)
  • /tldr count:<n> — summarize last N messages (max 200)
  • /tldr hours:<n> — summarize last N hours of messages
  • Ephemeral responses (deferReply({ ephemeral: true }) + safeEditReply)
  • Rich embed output: Key Topics, Decisions Made, Action Items, Notable Links
  • Per-channel rate limiting: 1 use per 5 minutes (in-memory Map)
  • tldr.enabled config gate via getConfig(guildId)
  • Uses @anthropic-ai/sdk with claude-haiku-4-5 for cost-efficient summarization
  • Input truncated to 100k chars to stay within context limits

config.json

Added tldr defaults:

{
  "tldr": {
    "enabled": false,
    "defaultMessages": 50,
    "maxMessages": 200,
    "cooldownSeconds": 300
  }
}

tests/commands/tldr.test.js

11 tests covering:

  • Default 50 message fetch
  • Count option respected
  • Hours option filters by time
  • Cooldown enforced (second call within 5 min rejected)
  • Cooldown allows call after expiry
  • Disabled config returns error
  • Empty channel / bot-only channel handled gracefully
  • AI response formatted into embed with all four sections

Test results

✓ tests/commands/tldr.test.js (11 tests) 12ms
Test Files  1 passed (1)
Tests  11 passed (11)

Full suite: 1657 tests pass, 0 failures, 0 biome errors.

Closes #25

Add a /tldr slash command that uses Claude Haiku to AI-summarize
recent Discord channel messages into a rich embed.

Features:
- /tldr              — summarize last 50 messages (default)
- /tldr count:<n>    — summarize last N messages (max 200)
- /tldr hours:<n>    — summarize last N hours of messages
- Rich embed: Key Topics, Decisions Made, Action Items, Notable Links
- Per-channel rate limiting (1 use per 5 minutes)
- tldr.enabled config gate via getConfig()
- Ephemeral responses via deferReply + safeEditReply

Also adds:
- @anthropic-ai/sdk as a direct dependency
- tldr defaults to config.json (enabled: false)
- 11 tests covering all core behaviors

Closes #25
Copilot AI review requested due to automatic review settings February 27, 2026 02:33
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

Warning

Rate limit exceeded

@BillChirico has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 31 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between a3d0639 and bbad921.

📒 Files selected for processing (5)
  • config.json
  • package.json
  • src/commands/help.js
  • src/commands/tldr.js
  • tests/commands/tldr.test.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/tldr-summarizer

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link

claude bot commented Feb 27, 2026

Claude finished @BillChirico's task in 3m 18s —— View job


Review: PR #105 — feat: /tldr conversation summarizer

  • Read AGENTS.md and CLAUDE.md for project conventions
  • Read changed files (tldr.js, tests, config.json, help.js, package.json)
  • Read existing patterns (permissions.js, rateLimit.js, other commands)
  • Analyze code quality, architecture, security, and testing
  • Post inline comments for specific issues
  • Post top-level summary with verdict

8 issues found (1 critical, 5 warnings, 2 nitpicks)

Note: The fix commit (bbad921) already addressed several issues from the first round of reviews (cooldown leak, module-level Anthropic client, cooldown timing, tldr permissions). The issues below are what remains.

# Severity File Issue
1 🔴 Critical src/commands/tldr.js:23 MAX_MESSAGE_COUNT = 200 exceeds Discord's 100-message-per-request API limit — will fail or silently cap at runtime
2 🟡 Warning src/commands/tldr.js:229 Enable gate === false lets command run when config is missing/undefined — should use !tldrConfig.enabled
3 🟡 Warning src/commands/tldr.js:269-276 Race condition — concurrent calls bypass cooldown since it's set after the AI call
4 🟡 Warning src/commands/tldr.js:5 Missing documentation updates (AGENTS.md Key Files, README.md features/config) — per AGENTS.md this is non-negotiable
5 🟡 Warning package.json:38 pnpm-lock.yaml not updated after adding @anthropic-ai/sdk
6 🟡 Warning tests/commands/tldr.test.js:206 Test asserts { limit: 200 } which exceeds Discord API max
7 🔵 Nitpick config.json:103-110 Unrelated starboard changes bundled in
8 🔵 Nitpick config.json:149 maxMessages: 200 config default not achievable without pagination
Prompt to fix all issues
Fix the following issues in the volvox-bot repo on branch feat/tldr-summarizer:

1. src/commands/tldr.js line 23: Change MAX_MESSAGE_COUNT from 200 to 100 (Discord API limit per request).

2. src/commands/tldr.js line 229: Change `if (tldrConfig.enabled === false)` to `if (!tldrConfig.enabled)` to match the pattern used in rateLimit.js and prevent the command from running when config is missing.

3. src/commands/tldr.js lines 269-276: Fix the race condition by setting a sentinel cooldown before the AI call, then clearing it on failure:
   - Before the AI call, add: cooldownMap.set(channelId, Date.now());
   - Wrap the AI call in try/catch: on failure, cooldownMap.delete(channelId) and re-throw
   - If summary is empty, cooldownMap.delete(channelId) before returning error
   - On success, refresh: cooldownMap.set(channelId, Date.now());

4. config.json line 149: Change "maxMessages": 200 to "maxMessages": 100.

5. tests/commands/tldr.test.js line 13 and 154: Update mock config maxMessages from 200 to 100.

6. tests/commands/tldr.test.js line 200: Update test config maxMessages from 200 to 100.

7. tests/commands/tldr.test.js line 206: Update assertion from { limit: 200 } to { limit: 100 }.

8. Run `pnpm install` to update pnpm-lock.yaml and commit it.

9. Update AGENTS.md Key Files table: add entry for `src/commands/tldr.js` with purpose "AI-powered /tldr conversation summarizer — fetches recent messages, calls Claude Haiku, returns structured embed".

10. Update README.md:
    - Add to Features list: "📋 TL;DR Summarizer — /tldr command summarizes recent channel conversations using AI, with configurable message count, time windows, and per-channel rate limiting."
    - Add a "TL;DR (`tldr`)" config table after the Starboard section with keys: enabled, defaultMessages, maxMessages, cooldownSeconds.

@greptile-apps
Copy link

greptile-apps bot commented Feb 27, 2026

Greptile Summary

Implements /tldr slash command for AI-powered conversation summarization using Claude Haiku 4.5. The implementation is well-structured and follows project conventions:

Strengths:

  • Clean code structure with proper separation of concerns
  • Uses Winston logging (no console.* calls) per AGENTS.md requirements
  • Ephemeral responses for user privacy
  • Module-level Anthropic client for connection pooling and reduced overhead
  • Per-channel cooldown with automatic cleanup to prevent memory leaks (fixed in HEAD commit)
  • Cooldown only set after successful AI response (good UX)
  • Comprehensive test coverage: 11 tests including edge cases, cooldowns, and error handling
  • Config-driven feature flag with sensible defaults
  • Proper error handling with try-catch and user-friendly error messages
  • Defensive programming (bot message filtering, truncation, fallback defaults)
  • Removed duplicate starboard config section

Documentation gap:

  • Per AGENTS.md line 177: "Added a new command → update Key Files table, add to README command list"
  • README.md should document the /tldr command (usage, options) and the tldr configuration section
  • This is the only gap preventing a perfect score

Test results: All 11 tests pass. Full suite: 1657 tests pass, 0 failures.

Confidence Score: 4/5

  • This PR is safe to merge with one minor documentation gap
  • Score reflects solid implementation with proper error handling, comprehensive test coverage (11/11 tests pass), and adherence to project conventions. The only gap is README documentation per AGENTS.md requirements — easily addressed in follow-up
  • No files require special attention — implementation is production-ready

Important Files Changed

Filename Overview
src/commands/tldr.js New AI conversation summarizer with proper error handling, cooldown management, Winston logging, ephemeral responses, and connection pooling via module-level Anthropic client
tests/commands/tldr.test.js Comprehensive test suite with 11 tests covering default behavior, options, cooldowns, edge cases, and disabled config
config.json Added tldr config section with sensible defaults, added permission entry, removed duplicate starboard section
package.json Added @anthropic-ai/sdk dependency for direct API access in tldr command
src/commands/help.js Minor formatting improvement to split a long line for better readability

Sequence Diagram

sequenceDiagram
    participant User
    participant Discord
    participant tldr.js
    participant Config
    participant Cooldown
    participant Channel
    participant Anthropic
    
    User->>Discord: /tldr [count|hours]
    Discord->>tldr.js: execute(interaction)
    tldr.js->>Discord: deferReply (ephemeral)
    
    tldr.js->>Config: getConfig(guildId)
    Config-->>tldr.js: tldr config
    
    alt Feature disabled
        tldr.js->>Discord: Command not enabled
    else Feature enabled
        tldr.js->>Cooldown: checkCooldown(channelId)
        Cooldown-->>tldr.js: cooldown status
        
        alt On cooldown
            tldr.js->>Discord: Wait X seconds
        else Cooldown OK
            tldr.js->>Channel: messages.fetch()
            Channel-->>tldr.js: message collection
            
            tldr.js->>tldr.js: Filter bots & format
            
            alt No messages
                tldr.js->>Discord: No messages found
            else Messages exist
                tldr.js->>Anthropic: summarize (Haiku 4.5)
                Anthropic-->>tldr.js: AI summary
                
                alt AI failed
                    tldr.js->>Discord: Failed to summarize
                else AI success
                    tldr.js->>Cooldown: Set cooldown
                    tldr.js->>tldr.js: Parse & build embed
                    tldr.js->>Discord: Rich embed with sections
                end
            end
        end
    end
Loading

Last reviewed commit: bbad921

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link

greptile-apps bot commented Feb 27, 2026

Additional Comments (1)

config.json
Missing tldr command in allowedCommands. Per src/utils/permissions.js:98-100, commands not in this list default to admin-only. Add entry to control access level:

    "allowedCommands": {
      "ping": "everyone",
      "memory": "everyone",
      "config": "admin",
      "warn": "admin",
      "kick": "admin",
      "timeout": "admin",
      "untimeout": "admin",
      "ban": "admin",
      "tempban": "admin",
      "unban": "admin",
      "softban": "admin",
      "purge": "admin",
      "case": "admin",
      "history": "admin",
      "lock": "admin",
      "unlock": "admin",
      "slowmode": "admin",
      "modlog": "moderator",
      "announce": "moderator",
      "tldr": "everyone"
    }
Prompt To Fix With AI
This is a comment left during a code review.
Path: config.json
Line: 128-148

Comment:
Missing `tldr` command in `allowedCommands`. Per `src/utils/permissions.js:98-100`, commands not in this list default to admin-only. Add entry to control access level:

```suggestion
    "allowedCommands": {
      "ping": "everyone",
      "memory": "everyone",
      "config": "admin",
      "warn": "admin",
      "kick": "admin",
      "timeout": "admin",
      "untimeout": "admin",
      "ban": "admin",
      "tempban": "admin",
      "unban": "admin",
      "softban": "admin",
      "purge": "admin",
      "case": "admin",
      "history": "admin",
      "lock": "admin",
      "unlock": "admin",
      "slowmode": "admin",
      "modlog": "moderator",
      "announce": "moderator",
      "tldr": "everyone"
    }
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

6 issues found (1 critical, 4 warnings, 1 nitpick). See inline comments for details.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new /tldr slash command that summarizes recent channel conversation using Anthropic Claude Haiku, returning a structured embed (topics/decisions/actions/links) with ephemeral delivery, plus associated configuration defaults and tests.

Changes:

  • Introduces src/commands/tldr.js implementing /tldr with count/hours options, cooldown, and Anthropic summarization.
  • Adds tests/commands/tldr.test.js covering option parsing, cooldown behavior, empty channels, and embed formatting.
  • Updates dependencies/configuration (adds @anthropic-ai/sdk, adds tldr defaults in config.json) and a small help command formatting tweak.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/commands/tldr.js New TLDR command implementation (message fetch, rate limit, Anthropic call, embed formatting).
tests/commands/tldr.test.js New unit tests for TLDR command behavior and output shaping.
config.json Adds tldr default config; also includes starboard section cleanup/adjustments.
package.json Adds @anthropic-ai/sdk dependency.
src/commands/help.js Formatting-only change for option builder chaining.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

8 issues found (1 critical, 5 warnings, 2 nitpicks). The critical issue is that MAX_MESSAGE_COUNT=200 exceeds Discord's API limit of 100 messages per fetch request, which will cause runtime failures. See inline comments for all details.

@BillChirico BillChirico merged commit 8ac54cf into main Feb 27, 2026
8 of 9 checks passed
@BillChirico BillChirico deleted the feat/tldr-summarizer branch February 27, 2026 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Conversation summarizer — /tldr to summarize recent channel activity

2 participants