Skip to content

fix: log AI responses and user messages to conversations with guild_id#183

Merged
BillChirico merged 13 commits intomainfrom
fix/conversation-logging
Mar 1, 2026
Merged

fix: log AI responses and user messages to conversations with guild_id#183
BillChirico merged 13 commits intomainfrom
fix/conversation-logging

Conversation

@BillChirico
Copy link
Collaborator

Summary

Fix conversation logging to actually store messages in production and include guild_id.

Problem

  • addToHistory() was defined but never called in production code
  • guild_id column existed but was never populated
  • triage-respond.js sent AI responses without logging them

Changes

  • src/modules/ai.js: Add guildId parameter to addToHistory(), update INSERT
  • src/modules/triage-respond.js: Import addToHistory, call after sending AI responses
  • src/modules/triage.js: Import addToHistory, call for user messages in accumulateMessage()
  • tests: Update expectations for 6 parameters

Files Changed

  • src/modules/ai.js — Add guildId param, update INSERT statement
  • src/modules/triage-respond.js — Log AI responses after sending
  • src/modules/triage.js — Log user messages in accumulateMessage()
  • tests/modules/ai.test.js — Update test expectations
  • tests/modules/ai.coverage.test.js — Update test expectations

Testing

  • All ai.test.js and ai.coverage.test.js tests pass
  • Pre-existing index.test.js failures unrelated to this change

Related

  • #182 — AI response feedback (requires conversation data)

- Add guild_id parameter to addToHistory() function
- Update INSERT to include guild_id column
- Call addToHistory() when sending AI responses in triage-respond.js
- Call addToHistory() for user messages in accumulateMessage()
- Update tests to expect 6 parameters instead of 5
Copilot AI review requested due to automatic review settings March 1, 2026 22:30
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an optional trailing guildId parameter to addToHistory, persists guild_id in the conversations DB insert (nullable), logs guild-aware user and assistant messages (including split assistant chunks) via addToHistory, and updates tests to expect the extra DB parameter.

Changes

Cohort / File(s) Summary
Core History Function
src/modules/ai.js
Added trailing guildId parameter to addToHistory signature and JSDoc. DB INSERT now includes guild_id (passes null when absent). In-memory trimming unchanged. DB error logs include guildId.
Triage / Message Logging
src/modules/triage.js, src/modules/triage-respond.js
triage.js now acquires live config per invocation, truncates/filters messages, captures reply context, and calls addToHistory for user messages. triage-respond.js imports addToHistory and logs each assistant message (including split chunks) with guildId.
Tests & Mocks
tests/modules/ai.coverage.test.js, tests/modules/ai.test.js, tests/modules/triage.test.js
Updated test expectations for DB INSERT parameter arrays to include extra trailing guildId (usually null). Added mocks for src/modules/ai.js and src/modules/config.js to drive triage tests with live config.

Possibly related PRs

Suggested reviewers

  • claude
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding guild_id to conversation logging and implementing the actual logging functionality for AI responses and user messages.
Description check ✅ Passed The description is detailed and directly related to the changeset, clearly explaining the problem, changes made, and testing performed.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/conversation-logging

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.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 1, 2026

Note

Docstrings generation - SUCCESS
Generated docstrings and committed to branch fix/conversation-logging (commit: c7c187db3512bd91d67c9788e9fcb5c4cbdcc551)

@coveralls
Copy link

coveralls commented Mar 1, 2026

Coverage Status

coverage: 90.123% (+0.002%) from 90.121%
when pulling dc0ba14 on fix/conversation-logging
into f576bf1 on main.

Docstrings generation was requested by @BillChirico.

The following files were modified:

* `src/modules/ai.js`
* `src/modules/triage.js`

These files were kept as they were:
* `src/modules/triage-respond.js`

These files were ignored:
* `tests/modules/ai.coverage.test.js`
* `tests/modules/ai.test.js`
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

This PR fixes conversation logging so that both user messages and AI responses are actually persisted to the conversations table in production, and includes guild_id so the existing conversations API (which filters by guild_id) can retrieve those rows.

Changes:

  • Extend addToHistory() to accept guildId and persist it in the conversations INSERT.
  • Call addToHistory() from triage to log user messages during accumulateMessage().
  • Call addToHistory() from triage responder to log assistant messages after sending responses.
  • Update AI module tests to expect the additional SQL parameter.

Reviewed changes

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

Show a summary per file
File Description
src/modules/ai.js Adds guildId support to persisted conversation history rows.
src/modules/triage.js Logs incoming user messages into the conversation history/DB.
src/modules/triage-respond.js Logs outgoing assistant messages into the conversation history/DB after sending.
tests/modules/ai.test.js Updates DB write-through expectation to include guild_id param.
tests/modules/ai.coverage.test.js Updates DB write-through expectation to include guild_id param.

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/modules/ai.js (1)

208-216: ⚠️ Potential issue | 🟠 Major

Use guild-scoped config when trimming history.

addToHistory now receives guildId, but trimming still uses getHistoryLength() with no guild argument. That can apply the wrong history limit in multi-guild setups and miss per-guild config updates.

Suggested fix
-function getHistoryLength() {
+function getHistoryLength(guildId = null) {
   try {
-    const config = getConfig();
+    const config = getConfig(guildId);
     const len = config?.ai?.historyLength;
     if (typeof len === 'number' && len > 0) return len;
   } catch {
     // Config not loaded yet, use default
   }
   return DEFAULT_HISTORY_LENGTH;
 }
@@
 export function addToHistory(channelId, role, content, username, discordMessageId, guildId) {
@@
-  const maxHistory = getHistoryLength();
+  const maxHistory = getHistoryLength(guildId);

As per coding guidelines src/modules/*.js: “Per-request modules (AI, spam, moderation) should call getConfig(guildId) on every invocation for automatic config changes.”

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/ai.js` around lines 208 - 216, The trimming logic in addToHistory
uses a global getHistoryLength() but addToHistory now receives guildId; update
addToHistory to fetch per-guild config by calling getConfig(guildId) (or
otherwise pass guildId into getHistoryLength if that function supports it) and
compute maxHistory from that per-guild config before trimming
conversationHistory for the channel; ensure you reference addToHistory,
getConfig, getHistoryLength, and conversationHistory when making the change so
history limits respect guild-scoped settings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/modules/triage-respond.js`:
- Around line 218-230: The moderation-path responses in triage-respond.js are
not being recorded to conversation history; ensure every message sent by
safeSend in both the normal and moderation branches calls addToHistory with the
same parameters (channelId, 'assistant', the message text/chunk used, null for
username, the sent message id, and channel.guild?.id || null). Locate the
moderation branch where a moderation response is sent (the variable analogous to
sentMsg or the safeSend call in that branch) and add an addToHistory call
mirroring the one after safeSend in the normal loop so moderated assistant
outputs are persisted.

---

Outside diff comments:
In `@src/modules/ai.js`:
- Around line 208-216: The trimming logic in addToHistory uses a global
getHistoryLength() but addToHistory now receives guildId; update addToHistory to
fetch per-guild config by calling getConfig(guildId) (or otherwise pass guildId
into getHistoryLength if that function supports it) and compute maxHistory from
that per-guild config before trimming conversationHistory for the channel;
ensure you reference addToHistory, getConfig, getHistoryLength, and
conversationHistory when making the change so history limits respect
guild-scoped settings.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f576bf1 and 4a1a17e.

📒 Files selected for processing (5)
  • src/modules/ai.js
  • src/modules/triage-respond.js
  • src/modules/triage.js
  • tests/modules/ai.coverage.test.js
  • tests/modules/ai.test.js
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Greptile Review
  • GitHub Check: Agent
  • GitHub Check: Docker Build Validation
🧰 Additional context used
📓 Path-based instructions (4)
**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

**/*.js: Use ESM modules — use import/export, never require()
Always use node: protocol for Node.js builtins (e.g. import { readFileSync } from 'node:fs')
Always use semicolons in JavaScript code
Use single quotes for strings (enforced by Biome)
Use 2-space indentation (enforced by Biome)

Files:

  • src/modules/triage-respond.js
  • tests/modules/ai.coverage.test.js
  • tests/modules/ai.test.js
  • src/modules/triage.js
  • src/modules/ai.js
src/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.js: Always use Winston logger — import { info, warn, error } from '../logger.js'. NEVER use console.log, console.warn, console.error, or any console.* method in src/ files — replace any existing console calls with Winston equivalents
Pass structured metadata to Winston logs: info('Message processed', { userId, channelId })

Files:

  • src/modules/triage-respond.js
  • src/modules/triage.js
  • src/modules/ai.js
src/modules/*.js

📄 CodeRabbit inference engine (AGENTS.md)

Per-request modules (AI, spam, moderation) should call getConfig(guildId) on every invocation for automatic config changes. Stateful resources should use onConfigChange listeners for reactive updates

Files:

  • src/modules/triage-respond.js
  • src/modules/triage.js
  • src/modules/ai.js
tests/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

All new code must include tests. Test coverage must maintain an 80% threshold on statements, branches, functions, and lines. Run pnpm test before every commit

Files:

  • tests/modules/ai.coverage.test.js
  • tests/modules/ai.test.js
🧠 Learnings (2)
📚 Learning: 2026-03-01T06:03:34.399Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-01T06:03:34.399Z
Learning: Use `splitMessage()` utility for messages exceeding Discord's 2000-character limit

Applied to files:

  • src/modules/triage-respond.js
📚 Learning: 2026-03-01T06:03:34.399Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-01T06:03:34.399Z
Learning: Applies to src/modules/*.js : Per-request modules (AI, spam, moderation) should call `getConfig(guildId)` on every invocation for automatic config changes. Stateful resources should use `onConfigChange` listeners for reactive updates

Applied to files:

  • src/modules/ai.js
🧬 Code graph analysis (4)
src/modules/triage-respond.js (2)
src/utils/safeSend.js (1)
  • safeSend (116-123)
src/modules/ai.js (2)
  • addToHistory (208-241)
  • channelId (278-278)
tests/modules/ai.test.js (1)
tests/utils/debugFooter.test.js (1)
  • mockQuery (5-5)
src/modules/triage.js (1)
src/modules/ai.js (2)
  • addToHistory (208-241)
  • channelId (278-278)
src/modules/ai.js (3)
src/modules/triage-respond.js (1)
  • guildId (284-284)
src/index.js (1)
  • guildId (182-182)
src/deploy-commands.js (1)
  • guildId (26-26)
🔇 Additional comments (3)
tests/modules/ai.coverage.test.js (1)

183-186: Expectation update is correct for the new DB argument shape.

This assertion now matches the 6-parameter insert path including guildId.

src/modules/triage.js (1)

601-609: Good addition: user messages now persist with guild and Discord message IDs.

This is the right call-site wiring for conversation traceability.

tests/modules/ai.test.js (1)

152-155: Test expectation correctly reflects the new guildId parameter.

The DB write assertion now matches the 6-value insert payload.

@greptile-apps
Copy link

greptile-apps bot commented Mar 1, 2026

Greptile Summary

This PR successfully fixes conversation logging by implementing the missing calls to addToHistory() and populating the guild_id column for both user messages and AI responses. The implementation is clean and follows project conventions:

Key changes:

  • Extended addToHistory() to accept guildId as a 6th parameter
  • User messages are now logged in accumulateMessage() when messages enter the triage buffer
  • AI responses are logged in triage-respond.js after successful message sends via new logAssistantHistory() helper
  • Properly handles null guild_id for DMs using optional chaining (message.guild?.id || null)
  • accumulateMessage() now uses dynamic config fetch via getConfig() instead of the passed parameter

Security & Best Practices:

  • SQL uses parameterized queries ($1-$6) preventing injection
  • Database writes are fire-and-forget with proper error logging
  • Winston logger used throughout (no console methods)
  • ESM imports used correctly
  • Error handling includes try-catch blocks with contextual logging

Testing:

  • All test files updated to match new 6-parameter signature
  • New tests verify guildId parameter is passed correctly
  • Tests cover both guild messages and DMs (null guildId)

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The implementation is straightforward, well-tested, and follows all project security and coding standards. SQL queries use proper parameterization, error handling is comprehensive, and the changes are covered by tests. Previous issues mentioned in review threads have been resolved.
  • No files require special attention

Important Files Changed

Filename Overview
src/modules/ai.js Added guildId parameter to addToHistory() and updated SQL INSERT to include guild_id column with proper parameterized query
src/modules/triage-respond.js Imported addToHistory and created helper to log AI responses after sending; handles both single messages and arrays correctly
src/modules/triage.js Imported addToHistory and calls it for user messages in accumulateMessage(); switched to dynamic config fetch via getConfig()
tests/modules/ai.test.js Updated test expectations for 6-parameter signature; added test coverage for guildId parameter
tests/modules/ai.coverage.test.js Updated test expectations to include the new guildId parameter (6th parameter)
tests/modules/triage.test.js Added mocks for addToHistory and getConfig; added tests verifying user messages are logged with correct parameters including guildId

Sequence Diagram

sequenceDiagram
    participant User
    participant Discord
    participant accumulateMessage
    participant addToHistory
    participant Database
    participant Triage
    participant sendResponses

    User->>Discord: Send message
    Discord->>accumulateMessage: message event
    accumulateMessage->>addToHistory: Log user message<br/>(role: 'user', guildId)
    addToHistory->>Database: INSERT conversation<br/>(includes guild_id)
    
    Note over Triage: Periodic evaluation or<br/>trigger word detected
    
    Triage->>Triage: Classify & generate response
    Triage->>sendResponses: Send AI response
    sendResponses->>Discord: safeSend(message)
    Discord-->>sendResponses: Message object(s)
    sendResponses->>addToHistory: Log AI response<br/>(role: 'assistant', guildId)
    addToHistory->>Database: INSERT conversation<br/>(includes guild_id)
Loading

Last reviewed commit: 66153ce

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/modules/ai.js (1)

209-217: ⚠️ Potential issue | 🟠 Major

Pass guild-scoped config into history trimming.

Line 216 still uses getHistoryLength() without guild context, even though Line 209 now receives guildId. In multi-guild usage this can apply the wrong config and miss per-request config refresh behavior.

Suggested fix
-function getHistoryLength() {
+function getHistoryLength(guildId = null) {
   try {
-    const config = getConfig();
+    const config = getConfig(guildId);
     const len = config?.ai?.historyLength;
     if (typeof len === 'number' && len > 0) return len;
   } catch {
     // Config not loaded yet, use default
   }
   return DEFAULT_HISTORY_LENGTH;
 }

 export function addToHistory(channelId, role, content, username, discordMessageId, guildId) {
@@
-  const maxHistory = getHistoryLength();
+  const maxHistory = getHistoryLength(guildId);

As per coding guidelines: "Per-request modules (AI, spam, moderation) should call getConfig(guildId) on every invocation for automatic config changes."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/ai.js` around lines 209 - 217, addToHistory must fetch per-guild
config and use it when computing max history: call getConfig(guildId) at the
start of addToHistory, then derive maxHistory from that config (either by
passing the config/guildId into getHistoryLength or reading
config.historyLength) and use that value for trimming. Update references to
getHistoryLength() in addToHistory to use the guild-scoped config so per-request
config changes are honored (function: addToHistory; helper: getConfig and
getHistoryLength or config.historyLength).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/modules/triage.js`:
- Line 33: The import ordering in triage.js is incorrect; move or reorder the
import of addToHistory (import { addToHistory } from './ai.js') so that imports
are sorted per the project's Biome rules (or run Biome --fix) to resolve the
"imports/exports not sorted" CI failure; specifically ensure addToHistory's
import is placed in the correct alphabetical/grouping position among other
imports in the module (or run the auto-fix) so the file's import block complies
with the linter.

---

Outside diff comments:
In `@src/modules/ai.js`:
- Around line 209-217: addToHistory must fetch per-guild config and use it when
computing max history: call getConfig(guildId) at the start of addToHistory,
then derive maxHistory from that config (either by passing the config/guildId
into getHistoryLength or reading config.historyLength) and use that value for
trimming. Update references to getHistoryLength() in addToHistory to use the
guild-scoped config so per-request config changes are honored (function:
addToHistory; helper: getConfig and getHistoryLength or config.historyLength).

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4a1a17e and c7c187d.

📒 Files selected for processing (2)
  • src/modules/ai.js
  • src/modules/triage.js
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (3)
**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

**/*.js: Use ESM modules — use import/export, never require()
Always use node: protocol for Node.js builtins (e.g. import { readFileSync } from 'node:fs')
Always use semicolons in JavaScript code
Use single quotes for strings (enforced by Biome)
Use 2-space indentation (enforced by Biome)

Files:

  • src/modules/ai.js
  • src/modules/triage.js
src/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.js: Always use Winston logger — import { info, warn, error } from '../logger.js'. NEVER use console.log, console.warn, console.error, or any console.* method in src/ files — replace any existing console calls with Winston equivalents
Pass structured metadata to Winston logs: info('Message processed', { userId, channelId })

Files:

  • src/modules/ai.js
  • src/modules/triage.js
src/modules/*.js

📄 CodeRabbit inference engine (AGENTS.md)

Per-request modules (AI, spam, moderation) should call getConfig(guildId) on every invocation for automatic config changes. Stateful resources should use onConfigChange listeners for reactive updates

Files:

  • src/modules/ai.js
  • src/modules/triage.js
🧠 Learnings (1)
📚 Learning: 2026-03-01T06:03:34.399Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-01T06:03:34.399Z
Learning: Applies to src/modules/*.js : Per-request modules (AI, spam, moderation) should call `getConfig(guildId)` on every invocation for automatic config changes. Stateful resources should use `onConfigChange` listeners for reactive updates

Applied to files:

  • src/modules/ai.js
🧬 Code graph analysis (2)
src/modules/ai.js (4)
src/modules/triage.js (1)
  • channelId (567-567)
src/modules/triage-respond.js (1)
  • guildId (284-284)
src/index.js (1)
  • guildId (182-182)
src/deploy-commands.js (1)
  • guildId (26-26)
src/modules/triage.js (1)
src/modules/ai.js (2)
  • addToHistory (209-242)
  • channelId (279-279)
🪛 GitHub Actions: CI
src/modules/triage.js

[error] 18-18: Biome: Imports and exports are not sorted. Auto-fix available.

🔇 Additional comments (2)
src/modules/ai.js (1)

228-237: Guild ID persistence and logging context look correct.

Line 228-Line 230 correctly persists guild_id, and Line 237 adds guildId to structured error metadata for DB-write failure diagnosis.

src/modules/triage.js (1)

606-614: User-message conversation logging is correctly integrated.

Line 606-Line 614 logs the sanitized buffered user message with channel/message context and guild fallback, which aligns with the PR objective.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/modules/triage-respond.js`:
- Around line 181-191: safeSend can return an array of message objects, but the
current check only logs history when sentMsg is non-array, causing dropped
history entries; update the logic around safeSend (the call at triage-respond.js
where sentMsg is awaited) to handle both single Message and Array<Message>
returns by iterating when Array.isArray(sentMsg) and calling addToHistory for
each individual message (preserving channelId, 'assistant', the corresponding
chunks[i] content, null, each message.id, and channel.guild?.id || null); apply
the same change to the equivalent block handling chunks at the other occurrence
(the block around addToHistory at lines ~228-239) so all returned messages are
persisted.

In `@src/modules/triage.js`:
- Around line 555-565: The accumulateMessage function currently uses the passed
msgConfig instead of fetching per-invocation settings; update accumulateMessage
to call getConfig(guildId) at the start (use message.guild?.id or guildId
extracted from message) and use that result for all triage behavior (enabled
flag, maxBufferSize, trigger words, timers) rather than the msgConfig parameter;
remove or ignore the incoming msgConfig where used (e.g., checks for triage
enabled, buffer size, trigger-word logic) so runtime config updates take effect.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c7c187d and dc0ba14.

📒 Files selected for processing (2)
  • src/modules/triage-respond.js
  • src/modules/triage.js
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (3)
**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

**/*.js: Use ESM modules — use import/export, never require()
Always use node: protocol for Node.js builtins (e.g. import { readFileSync } from 'node:fs')
Always use semicolons in JavaScript code
Use single quotes for strings (enforced by Biome)
Use 2-space indentation (enforced by Biome)

Files:

  • src/modules/triage-respond.js
  • src/modules/triage.js
src/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.js: Always use Winston logger — import { info, warn, error } from '../logger.js'. NEVER use console.log, console.warn, console.error, or any console.* method in src/ files — replace any existing console calls with Winston equivalents
Pass structured metadata to Winston logs: info('Message processed', { userId, channelId })

Files:

  • src/modules/triage-respond.js
  • src/modules/triage.js
src/modules/*.js

📄 CodeRabbit inference engine (AGENTS.md)

Per-request modules (AI, spam, moderation) should call getConfig(guildId) on every invocation for automatic config changes. Stateful resources should use onConfigChange listeners for reactive updates

Files:

  • src/modules/triage-respond.js
  • src/modules/triage.js
🧠 Learnings (2)
📚 Learning: 2026-03-01T06:03:34.399Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-01T06:03:34.399Z
Learning: Applies to src/commands/*.js : Moderation commands must follow the shared pattern: `deferReply({ ephemeral: true })`, validate inputs, `sendDmNotification()`, execute Discord action, `createCase()`, `sendModLogEmbed()`, `checkEscalation()`

Applied to files:

  • src/modules/triage-respond.js
📚 Learning: 2026-03-01T06:03:34.399Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-01T06:03:34.399Z
Learning: Use `splitMessage()` utility for messages exceeding Discord's 2000-character limit

Applied to files:

  • src/modules/triage-respond.js
🧬 Code graph analysis (2)
src/modules/triage-respond.js (2)
src/utils/safeSend.js (1)
  • safeSend (116-123)
src/modules/ai.js (2)
  • addToHistory (209-242)
  • channelId (279-279)
src/modules/triage.js (1)
src/modules/ai.js (2)
  • addToHistory (209-242)
  • channelId (279-279)
🔇 Additional comments (3)
src/modules/triage-respond.js (1)

11-11: Good import wiring for conversation persistence.

addToHistory is imported cleanly and aligns with the updated assistant-history flow.

src/modules/triage.js (2)

26-26: addToHistory import integration looks good.

This import cleanly enables user-message persistence in the triage flow.


612-620: No action needed — bot-message filtering is already in place.

The bot guard (if (message.author.bot) return;) at line 122 in src/modules/events.js executes before any call to accumulateMessage. Both accumulateMessage calls (lines 226 and 259) are downstream from this guard and therefore only process non-bot messages. Assistant outputs cannot be stored as user messages through this code path.

Copilot AI review requested due to automatic review settings March 1, 2026 22:52
coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 1, 2026
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

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


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

User message logging in accumulateMessage broke triage tests due to
missing mocks. AI responses are still logged in triage-respond.js.

Reverts user message logging - can add back with proper test mocks later.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/modules/triage.js (1)

557-610: ⚠️ Potential issue | 🟠 Major

User messages are still not persisted to conversation history.

accumulateMessage documents that it records messages in history, but after buffering (Line 610) there is no addToHistory(...) call. This leaves conversation records incomplete and misses the user-turn logging objective.

Suggested fix
+import { addToHistory } from './ai.js';
 import { getConfig } from './config.js';
@@
   // Push to ring buffer (with truncation warning)
   pushToBuffer(channelId, entry, maxBufferSize);
+
+  // Persist user message to conversation history
+  addToHistory(
+    channelId,
+    'user',
+    entry.content,
+    message.author.username || null,
+    message.id,
+    message.guild?.id || null,
+  );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/triage.js` around lines 557 - 610, accumulateMessage builds a
buffer entry but never persists the same data to conversation history; after
pushToBuffer(channelId, entry, maxBufferSize) add a call to the history
persistence function (e.g., addToHistory or whatever history writer is used in
the module) passing the entry and channel/guild context so the user turn is
recorded (include entry, channelId and message.guild?.id or null). Ensure you
call the same sanitized/truncated entry (including replyTo) so buffer and
history stay consistent and handle any errors from addToHistory with debug
logging.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/modules/triage.js`:
- Around line 557-610: accumulateMessage builds a buffer entry but never
persists the same data to conversation history; after pushToBuffer(channelId,
entry, maxBufferSize) add a call to the history persistence function (e.g.,
addToHistory or whatever history writer is used in the module) passing the entry
and channel/guild context so the user turn is recorded (include entry, channelId
and message.guild?.id or null). Ensure you call the same sanitized/truncated
entry (including replyTo) so buffer and history stay consistent and handle any
errors from addToHistory with debug logging.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc0ba14 and 9ca303a.

📒 Files selected for processing (2)
  • src/modules/triage-respond.js
  • src/modules/triage.js
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (3)
**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

**/*.js: Use ESM modules — use import/export, never require()
Always use node: protocol for Node.js builtins (e.g. import { readFileSync } from 'node:fs')
Always use semicolons in JavaScript code
Use single quotes for strings (enforced by Biome)
Use 2-space indentation (enforced by Biome)

Files:

  • src/modules/triage-respond.js
  • src/modules/triage.js
src/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.js: Always use Winston logger — import { info, warn, error } from '../logger.js'. NEVER use console.log, console.warn, console.error, or any console.* method in src/ files — replace any existing console calls with Winston equivalents
Pass structured metadata to Winston logs: info('Message processed', { userId, channelId })

Files:

  • src/modules/triage-respond.js
  • src/modules/triage.js
src/modules/*.js

📄 CodeRabbit inference engine (AGENTS.md)

Per-request modules (AI, spam, moderation) should call getConfig(guildId) on every invocation for automatic config changes. Stateful resources should use onConfigChange listeners for reactive updates

Files:

  • src/modules/triage-respond.js
  • src/modules/triage.js
🧠 Learnings (2)
📚 Learning: 2026-03-01T06:03:34.399Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-01T06:03:34.399Z
Learning: Applies to src/commands/*.js : Moderation commands must follow the shared pattern: `deferReply({ ephemeral: true })`, validate inputs, `sendDmNotification()`, execute Discord action, `createCase()`, `sendModLogEmbed()`, `checkEscalation()`

Applied to files:

  • src/modules/triage-respond.js
  • src/modules/triage.js
📚 Learning: 2026-03-01T06:03:34.399Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-01T06:03:34.399Z
Learning: Applies to src/modules/*.js : Per-request modules (AI, spam, moderation) should call `getConfig(guildId)` on every invocation for automatic config changes. Stateful resources should use `onConfigChange` listeners for reactive updates

Applied to files:

  • src/modules/triage.js
🧬 Code graph analysis (2)
src/modules/triage-respond.js (2)
src/modules/ai.js (2)
  • channelId (279-279)
  • addToHistory (209-242)
src/utils/safeSend.js (1)
  • safeSend (116-123)
src/modules/triage.js (2)
src/modules/config.js (2)
  • getConfig (282-313)
  • err (94-94)
src/modules/triage-filter.js (2)
  • triageConfig (52-52)
  • checkTriggerWords (51-65)
🔇 Additional comments (3)
src/modules/triage-respond.js (2)

32-38: Robust handling of safeSend return shapes in history helper.

This helper correctly handles both Message and Message[] results and avoids dropping history entries when splitting occurs.


204-205: History persistence is correctly applied in both response paths.

Wiring logAssistantHistory(...) in both moderation and normal send loops closes previous assistant-history gaps.

Also applies to: 242-244

src/modules/triage.js (1)

564-567: Per-invocation live config usage is correctly applied.

Using getConfig(message.guild?.id || null) and threading liveConfig through trigger evaluation and scheduling aligns this path with runtime config refresh behavior.

As per coding guidelines: src/modules/*.js: Per-request modules (AI, spam, moderation) should call getConfig(guildId) on every invocation for automatic config changes.

Also applies to: 613-618, 623-623

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 1, 2026
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.

6 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

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

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


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

Copilot AI review requested due to automatic review settings March 1, 2026 23:31
Copy link
Collaborator Author

@BillChirico BillChirico left a comment

Choose a reason for hiding this comment

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

Fixed: re-added addToHistory call in accumulateMessage() with proper vi.mock for ai.js and getConfig mock for tests. User messages are now logged to conversations with guild_id alongside AI responses. All 54 tests passing.

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

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.


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

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/modules/ai.test.js (1)

145-160: ⚠️ Potential issue | 🟠 Major

Add a positive-path test for non-null guildId persistence.

The updated assertion covers only guild_id = null. Please add one case that calls addToHistory(..., guildId) and asserts the 6th SQL parameter contains that guild ID.

🧪 Suggested test addition
   it('should write to DB when pool is available', () => {
@@
       ]);
     });
+
+    it('should persist guild_id when provided', () => {
+      const mockQuery = vi.fn().mockResolvedValue({});
+      setPool({ query: mockQuery });
+
+      addToHistory('ch1', 'user', 'hello', 'testuser', 'msg-1', 'guild-1');
+
+      expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO conversations'), [
+        'ch1',
+        'user',
+        'hello',
+        'testuser',
+        'msg-1',
+        'guild-1',
+      ]);
+    });

As per coding guidelines: tests/**/*.js: "All new code must include tests."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/modules/ai.test.js` around lines 145 - 160, Add a positive-path test
that calls addToHistory with a non-null guildId and asserts the SQL parameter
array includes that guildId in the 6th position: create a new it() similar to
the existing one, set a fresh mockQuery/mockPool, call addToHistory('chX',
'user', 'msg', 'testuser', 'GUILD_ID'), then
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO
conversations'), expect.arrayContaining([]) replaced by an explicit array where
the 6th element (index 5) equals 'GUILD_ID'); ensure you reference addToHistory
and the test's mockQuery/mockPool so the new test verifies the non-null guildId
persistence.
src/modules/triage.js (1)

590-608: ⚠️ Potential issue | 🟠 Major

Add timeout to referenced message fetch to prevent internal blocking.

The message.channel.messages.fetch() call at line 593 has no timeout. Even though external callers use fire-and-forget patterns (lines 226, 259 in events.js), the fetch blocks the internal pipeline—delaying pushToBuffer and scheduleEvaluation if the Discord API is slow or unresponsive. Your codebase already uses Promise.race with timeouts elsewhere (line 135-138 for memory context). Apply the same pattern here with a 500ms timeout for message fetches.

⏱️ Suggested bounded fetch
   if (message.reference?.messageId) {
     try {
-      const ref = await message.channel.messages.fetch(message.reference.messageId);
+      const ref = await Promise.race([
+        message.channel.messages.fetch(message.reference.messageId),
+        new Promise((_, reject) =>
+          setTimeout(() => reject(new Error('Referenced message fetch timeout')), 500),
+        ),
+      ]);
       entry.replyTo = {
         author: ref.author.username,
         userId: ref.author.id,
         content: sanitizeText(ref.content?.slice(0, 500)) || '',
         messageId: ref.id,
       };
     } catch (err) {
       debug('Referenced message fetch failed', {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/triage.js` around lines 590 - 608, The referenced-message fetch
(message.channel.messages.fetch) can block the pipeline—wrap that fetch in a
bounded promise using Promise.race with a 500ms timeout and abort/failover if
the timeout elapses; on success populate entry.replyTo as before (author,
userId, sanitized content, messageId), and on timeout or error call the existing
debug(...) branch to log channelId, messageId, referenceId and the timeout error
message; use the same timeout pattern used for memory context (the Promise.race
timeout helper used around memory context code) to implement this change.
♻️ Duplicate comments (1)
src/modules/triage.js (1)

18-48: ⚠️ Potential issue | 🟠 Major

Organize imports to resolve the current Biome CI failure.

The file still fails Organize Imports (pipeline error at Line 18). Please run Biome import organization on this module.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/triage.js` around lines 18 - 48, Run the Biome import organizer
on this module to fix the Organize Imports CI failure; reorder and group the
imports (external libs first, then local modules, then sub-module imports) and
remove any duplicate or unused imports such as duplicates of debug/info or
repeated block imports; ensure the existing symbols (debug, info,
error/logError, warn, loadPrompt, promptPath, safeSend, CLIProcess,
CLIProcessError, buildMemoryContext, extractAndStoreMemories, getConfig,
addToHistory, channelBuffers, clearEvaluatedMessages, consumePendingReeval,
pushToBuffer, getDynamicInterval, isChannelEligible, resolveTriageConfig,
checkTriggerWords, sanitizeText, parseClassifyResult, parseRespondResult,
buildClassifyPrompt, buildRespondPrompt, buildStatsAndLog, fetchChannelContext,
sendModerationLog, sendResponses) remain correctly imported and not duplicated
after organization.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/modules/triage.test.js`:
- Line 68: The mock implementation for getConfig in tests/modules/triage.test.js
declares an unused parameter named guildId which triggers a lint warning; update
the mock (getConfig: vi.fn(...)) to either remove the parameter or rename it to
_guildId (e.g., getConfig: vi.fn((_guildId) => mockGlobalConfig)) so the linter
recognizes it as intentionally unused and the CI warning is resolved.
- Around line 53-63: The test must assert that accumulateMessage invokes
addToHistory with the expected triage-side log payload: call
accumulateMessage(...) in the test with a sample message object (including
author.id, content, id, channel.id, guild?.id) and then expect the mocked
addToHistory to have been called once with an object containing those fields
(user/message content, user id, message id, channel id, guild id) and any
required context flags; also ensure you clear/reset mocks before the assertion.
Target the addToHistory mock and the accumulateMessage function name when adding
the expectation so the test directly verifies the new history-logging behavior.

---

Outside diff comments:
In `@src/modules/triage.js`:
- Around line 590-608: The referenced-message fetch
(message.channel.messages.fetch) can block the pipeline—wrap that fetch in a
bounded promise using Promise.race with a 500ms timeout and abort/failover if
the timeout elapses; on success populate entry.replyTo as before (author,
userId, sanitized content, messageId), and on timeout or error call the existing
debug(...) branch to log channelId, messageId, referenceId and the timeout error
message; use the same timeout pattern used for memory context (the Promise.race
timeout helper used around memory context code) to implement this change.

In `@tests/modules/ai.test.js`:
- Around line 145-160: Add a positive-path test that calls addToHistory with a
non-null guildId and asserts the SQL parameter array includes that guildId in
the 6th position: create a new it() similar to the existing one, set a fresh
mockQuery/mockPool, call addToHistory('chX', 'user', 'msg', 'testuser',
'GUILD_ID'), then
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO
conversations'), expect.arrayContaining([]) replaced by an explicit array where
the 6th element (index 5) equals 'GUILD_ID'); ensure you reference addToHistory
and the test's mockQuery/mockPool so the new test verifies the non-null guildId
persistence.

---

Duplicate comments:
In `@src/modules/triage.js`:
- Around line 18-48: Run the Biome import organizer on this module to fix the
Organize Imports CI failure; reorder and group the imports (external libs first,
then local modules, then sub-module imports) and remove any duplicate or unused
imports such as duplicates of debug/info or repeated block imports; ensure the
existing symbols (debug, info, error/logError, warn, loadPrompt, promptPath,
safeSend, CLIProcess, CLIProcessError, buildMemoryContext,
extractAndStoreMemories, getConfig, addToHistory, channelBuffers,
clearEvaluatedMessages, consumePendingReeval, pushToBuffer, getDynamicInterval,
isChannelEligible, resolveTriageConfig, checkTriggerWords, sanitizeText,
parseClassifyResult, parseRespondResult, buildClassifyPrompt,
buildRespondPrompt, buildStatsAndLog, fetchChannelContext, sendModerationLog,
sendResponses) remain correctly imported and not duplicated after organization.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9ca303a and 395e199.

📒 Files selected for processing (4)
  • src/modules/triage.js
  • tests/modules/ai.coverage.test.js
  • tests/modules/ai.test.js
  • tests/modules/triage.test.js
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Greptile Review
  • GitHub Check: Agent
🧰 Additional context used
📓 Path-based instructions (4)
**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

**/*.js: Use ESM modules — use import/export, never require()
Always use node: protocol for Node.js builtins (e.g. import { readFileSync } from 'node:fs')
Always use semicolons in JavaScript code
Use single quotes for strings (enforced by Biome)
Use 2-space indentation (enforced by Biome)

Files:

  • tests/modules/ai.coverage.test.js
  • src/modules/triage.js
  • tests/modules/triage.test.js
  • tests/modules/ai.test.js
tests/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

All new code must include tests. Test coverage must maintain an 80% threshold on statements, branches, functions, and lines. Run pnpm test before every commit

Files:

  • tests/modules/ai.coverage.test.js
  • tests/modules/triage.test.js
  • tests/modules/ai.test.js
src/**/*.js

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.js: Always use Winston logger — import { info, warn, error } from '../logger.js'. NEVER use console.log, console.warn, console.error, or any console.* method in src/ files — replace any existing console calls with Winston equivalents
Pass structured metadata to Winston logs: info('Message processed', { userId, channelId })

Files:

  • src/modules/triage.js
src/modules/*.js

📄 CodeRabbit inference engine (AGENTS.md)

Per-request modules (AI, spam, moderation) should call getConfig(guildId) on every invocation for automatic config changes. Stateful resources should use onConfigChange listeners for reactive updates

Files:

  • src/modules/triage.js
🧠 Learnings (2)
📚 Learning: 2026-03-01T06:03:34.399Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-01T06:03:34.399Z
Learning: Applies to src/modules/*.js : Per-request modules (AI, spam, moderation) should call `getConfig(guildId)` on every invocation for automatic config changes. Stateful resources should use `onConfigChange` listeners for reactive updates

Applied to files:

  • src/modules/triage.js
  • tests/modules/triage.test.js
📚 Learning: 2026-03-01T06:03:34.399Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-01T06:03:34.399Z
Learning: Applies to src/commands/*.js : Moderation commands must follow the shared pattern: `deferReply({ ephemeral: true })`, validate inputs, `sendDmNotification()`, execute Discord action, `createCase()`, `sendModLogEmbed()`, `checkEscalation()`

Applied to files:

  • src/modules/triage.js
🧬 Code graph analysis (2)
src/modules/triage.js (3)
src/modules/config.js (2)
  • getConfig (282-313)
  • err (94-94)
src/modules/triage-filter.js (2)
  • triageConfig (52-52)
  • checkTriggerWords (51-65)
src/modules/ai.js (2)
  • addToHistory (209-242)
  • channelId (279-279)
tests/modules/triage.test.js (2)
src/modules/triage.js (1)
  • config (60-60)
src/modules/ai.js (2)
  • config (34-34)
  • config (49-49)
🪛 GitHub Actions: CI
src/modules/triage.js

[error] 18-18: The imports and exports are not sorted. Biome fix: Organize Imports.

tests/modules/triage.test.js

[warning] 68-68: lint/correctness/noUnusedFunctionParameters: Unused parameter 'guildId'. If this is intentional, prefix with an underscore.

🔇 Additional comments (1)
tests/modules/ai.coverage.test.js (1)

183-190: DB insert expectation is correctly aligned with the new 6-parameter write.

This update matches the guild_id expansion and keeps the write-through assertion accurate.

Pip Build added 2 commits March 1, 2026 18:47
Add two new test cases in the accumulateMessage describe block:
- verifies addToHistory is called with correct args for a guild message
  (channelId, 'user', content, author, messageId, guildId)
- verifies addToHistory receives null guildId for DMs (no guild property)

Addresses CodeRabbit thread PRRT_kwDORICdSM5xcDiy (major: core PR
behavior was not asserted in tests).
The existing DB write test only asserted that guildId was null in the
INSERT params. Add a new test that passes a real guildId ('guild-456')
and verifies it flows through to the INSERT statement.

Addresses Copilot review thread PRRT_kwDORICdSM5xb_9O.
coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 1, 2026
Copilot AI review requested due to automatic review settings March 1, 2026 23:53
@BillChirico BillChirico merged commit 135cd2e into main Mar 1, 2026
13 of 15 checks passed
@BillChirico BillChirico deleted the fix/conversation-logging branch March 1, 2026 23:56
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

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.


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

Comment on lines +19 to +38
/**
* Log an assistant message (or multiple messages when safeSend splits into an array)
* to conversation history.
*
* `safeSend` can return either a single Message object or an array of Message objects
* when the content was split across multiple Discord messages. Both cases are handled
* here so history is never silently dropped.
*
* @param {string} channelId - The channel the message was sent in.
* @param {string|null} guildId - The guild ID, or null for DMs.
* @param {string} fallbackContent - Text to use when the sent message has no `.content`.
* @param {import('discord.js').Message|import('discord.js').Message[]|null} sentMsg - Return value of safeSend.
*/
function logAssistantHistory(channelId, guildId, fallbackContent, sentMsg) {
const sentMessages = Array.isArray(sentMsg) ? sentMsg : [sentMsg];
for (const m of sentMessages) {
if (!m?.id) continue;
addToHistory(channelId, 'assistant', m.content || fallbackContent, null, m.id, guildId || null);
}
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

History logging for assistant responses was added via logAssistantHistory/addToHistory, but existing triage-respond tests don’t assert that history is recorded (including the safeSend single-message vs array return cases). Adding a focused unit test that mocks addToHistory and verifies the expected calls (channelId, role, content, discordMessageId, guildId) would prevent regressions in this production-critical logging path.

Copilot generated this review using guidance from organization custom instructions.
@BillChirico BillChirico restored the fix/conversation-logging branch March 2, 2026 00:46
@BillChirico BillChirico deleted the fix/conversation-logging branch March 2, 2026 00:59
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.

3 participants