Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/modules/ai.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,10 @@ export async function getHistoryAsync(channelId) {
* @param {string} role - Message role (e.g., "user" or "assistant").
* @param {string} content - Message text content.
* @param {string} [username] - Optional display name associated with the message.
* @param {string} [discordMessageId] - Optional native Discord message ID (used to construct jump URLs in the dashboard).
* @param {string} [discordMessageId] - Optional native Discord message ID
* @param {string} [guildId] - Optional guild ID for the conversation (used to construct jump URLs in the dashboard).
*/
export function addToHistory(channelId, role, content, username, discordMessageId) {
export function addToHistory(channelId, role, content, username, discordMessageId, guildId) {
if (!conversationHistory.has(channelId)) {
conversationHistory.set(channelId, []);
}
Expand All @@ -223,15 +224,16 @@ export function addToHistory(channelId, role, content, username, discordMessageI
if (pool) {
pool
.query(
`INSERT INTO conversations (channel_id, role, content, username, discord_message_id)
VALUES ($1, $2, $3, $4, $5)`,
[channelId, role, content, username || null, discordMessageId || null],
`INSERT INTO conversations (channel_id, role, content, username, discord_message_id, guild_id)
VALUES ($1, $2, $3, $4, $5, $6)`,
[channelId, role, content, username || null, discordMessageId || null, guildId || null],
)
.catch((err) => {
logError('Failed to persist message to DB', {
channelId,
role,
username: username || null,
guildId: guildId || null,
error: err.message,
});
});
Expand Down
15 changes: 14 additions & 1 deletion src/modules/triage-respond.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { info, error as logError, warn } from '../logger.js';
import { buildDebugEmbed, extractStats, logAiUsage } from '../utils/debugFooter.js';
import { safeSend } from '../utils/safeSend.js';
import { splitMessage } from '../utils/splitMessage.js';
import { addToHistory } from './ai.js';
import { resolveMessageId, sanitizeText } from './triage-filter.js';

/** Maximum characters to keep from fetched context messages. */
Expand Down Expand Up @@ -214,7 +215,19 @@ export async function sendResponses(
const msgOpts = { content: chunks[i] };
if (debugEmbed && i === 0) msgOpts.embeds = [debugEmbed];
if (replyRef && i === 0) msgOpts.reply = { messageReference: replyRef };
await safeSend(channel, msgOpts);
const sentMsg = await safeSend(channel, msgOpts);

// Log AI response to conversation history
if (sentMsg && !Array.isArray(sentMsg)) {
addToHistory(
channelId,
'assistant',
chunks[i],
null, // username - bot doesn't have one in this context
sentMsg.id,
channel.guild?.id || null
);
}
}

info('Triage response sent', {
Expand Down
11 changes: 11 additions & 0 deletions src/modules/triage.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
pushToBuffer,
} from './triage-buffer.js';
import { getDynamicInterval, isChannelEligible, resolveTriageConfig } from './triage-config.js';
import { addToHistory } from './ai.js';
import { checkTriggerWords, sanitizeText } from './triage-filter.js';
import { parseClassifyResult, parseRespondResult } from './triage-parse.js';
import { buildClassifyPrompt, buildRespondPrompt } from './triage-prompt.js';
Expand Down Expand Up @@ -597,6 +598,16 @@ export async function accumulateMessage(message, msgConfig) {
// Push to ring buffer (with truncation warning)
pushToBuffer(channelId, entry, maxBufferSize);

// Log user message to conversation history
addToHistory(
channelId,
'user',
entry.content,
entry.author,
entry.messageId,
message.guild?.id || null
);

// Check for trigger words -- instant evaluation
if (checkTriggerWords(message.content, msgConfig)) {
info('Trigger word detected, forcing evaluation', { channelId });
Expand Down
11 changes: 4 additions & 7 deletions tests/modules/ai.coverage.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,10 @@ describe('ai module coverage', () => {

// Give the fire-and-forget a tick to run
await new Promise((resolve) => setTimeout(resolve, 0));
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO conversations'), [
'ch1',
'user',
'hello',
'testuser',
null,
]);
expect(mockQuery).toHaveBeenCalledWith(
expect.stringContaining('INSERT INTO conversations'),
['ch1', 'user', 'hello', 'testuser', null, null]
);
});

it('logs error when DB write fails', async () => {
Expand Down
11 changes: 4 additions & 7 deletions tests/modules/ai.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,10 @@ describe('ai module', () => {

addToHistory('ch1', 'user', 'hello', 'testuser');

expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO conversations'), [
'ch1',
'user',
'hello',
'testuser',
null,
]);
expect(mockQuery).toHaveBeenCalledWith(
expect.stringContaining('INSERT INTO conversations'),
['ch1', 'user', 'hello', 'testuser', null, null]
);
});
});

Expand Down
Loading