feat(discord-gateway): add perceptual hash helpers for image deduplication in ai-moderation
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { existsSync } from "node:fs";
|
import { existsSync } from "node:fs";
|
||||||
|
import { availableParallelism } from "node:os";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
import { createChildLogger } from "@bete/shared/logger";
|
import { createChildLogger } from "@bete/shared/logger";
|
||||||
import { retryWithBackoff } from "@bete/shared/utils";
|
import { retryWithBackoff } from "@bete/shared/utils";
|
||||||
@@ -26,7 +27,7 @@ import type {
|
|||||||
ModerationBroadcaster,
|
ModerationBroadcaster,
|
||||||
} from "../message-capture/types.js";
|
} from "../message-capture/types.js";
|
||||||
import { attemptAutoDeleteFlaggedMessage } from "./autoDeleteManager.js";
|
import { attemptAutoDeleteFlaggedMessage } from "./autoDeleteManager.js";
|
||||||
import { buildConversationContext } from "./conversationContext.js";
|
import { buildConversationContext, estimateTokens } from "./conversationContext.js";
|
||||||
import { runModerationAnalysis } from "./llmModerationClient.js";
|
import { runModerationAnalysis } from "./llmModerationClient.js";
|
||||||
import { logModerationError } from "./responseLogger.js";
|
import { logModerationError } from "./responseLogger.js";
|
||||||
|
|
||||||
|
|||||||
@@ -190,31 +190,18 @@ export async function captureMessage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isBacklog) {
|
if (!isBacklog) {
|
||||||
if (attachmentUploadTasks.length > 0) {
|
// AI analysis starts immediately — attachment upload runs in parallel.
|
||||||
let analysisQueued = false;
|
// Media analysis path downloads images directly from Discord CDN,
|
||||||
let fallbackTimer: NodeJS.Timeout | null = null;
|
// so it does NOT depend on the upload completing first.
|
||||||
const queueAnalysisOnce = () => {
|
queueMessageAnalysis(message.id);
|
||||||
if (analysisQueued) return;
|
|
||||||
analysisQueued = true;
|
|
||||||
if (fallbackTimer) {
|
|
||||||
clearTimeout(fallbackTimer);
|
|
||||||
fallbackTimer = null;
|
|
||||||
}
|
|
||||||
queueMessageAnalysis(message.id);
|
|
||||||
};
|
|
||||||
|
|
||||||
fallbackTimer = setTimeout(queueAnalysisOnce, 30000);
|
if (attachmentUploadTasks.length > 0) {
|
||||||
Promise.allSettled(attachmentUploadTasks)
|
Promise.allSettled(attachmentUploadTasks).catch((err: unknown) => {
|
||||||
.then(queueAnalysisOnce)
|
logger.error(
|
||||||
.catch((err: unknown) => {
|
{ messageId: message.id, error: err },
|
||||||
logger.error(
|
"Attachment upload tasks failed",
|
||||||
{ messageId: message.id, error: err },
|
);
|
||||||
"Failed to queue message analysis after attachment upload",
|
});
|
||||||
);
|
|
||||||
queueAnalysisOnce();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
queueMessageAnalysis(message.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user