feat(moderation): skip AI analysis for music bots via AI_SKIP_ANALYSIS_USER_IDS

Jockie Music (user 411916947773587456) posts now-playing embeds/spotify links
~1347 captured messages — every one consumed a moderation LLM call for zero
signal and contributed to batch timeouts. Config AI_SKIP_ANALYSIS_USER_IDS
(default=Jockie) skips them at ALL three analysis paths:
- queueMessageAnalysis entry (direct skip-result like age-restricted)
- batchScheduler processing (pre-batch filter)
- individual recovery path (no fallback spam for already-skipped authors)

Skip-result mirrors age_restricted: status=clean, flags=[skip_analysis_user],
action=none — stays visible in the dashboard, never analyzed.
This commit is contained in:
asepharyana committed 2026-09-09 23:38:32 +07:00
1 parent db4e84f057
commit 023217b260
4 files changed
+93 -3

No files matched your search

@@ -7,8 +7,11 @@ import type { AnalysisQueueStatus } from "../message-capture/types.js";
import {
activeRequests,
buildAgeRestrictedSkipResult,
buildSkipAnalysisUserResult,
isAgeRestrictedMessage,
isSkipAnalysisUser,
skipAgeRestrictedMessages,
skipAnalysisUserMessages,
} from "./batchProcessor.js";
import { scheduleConversationAnalysis } from "./batchScheduler.js";
import { getConversationKey } from "./circuitBreaker.js";
@@ -84,6 +87,21 @@ export async function queueMessageAnalysis(messageId: string): Promise<void> {
return;
}
if (isSkipAnalysisUser(message)) {
const updated = await messageStore.updateMessageAIAnalysis(
message.id,
buildSkipAnalysisUserResult(),
);
if (updated) {
broadcastAnalysisCompleted(updated);
}
logger.debug(
{ messageId, userId: message.user_id },
"Skipped AI analysis for configured skip-list user",
);
return;
}
queueConversationAnalysis(getConversationKey(message));
} catch (error) {
logger.error(
@@ -240,8 +258,9 @@ export function startPendingAIAnalysisWorker(
messageStore
.getIncompleteMessagesByConversation(key, 500)
.then(async (msgs) => {
const processableMessages =
await skipAgeRestrictedMessages(msgs);
const processableMessages = await skipAnalysisUserMessages(
await skipAgeRestrictedMessages(msgs),
);
return processableMessages;
})
.then((msgs) => {