refactor: simplify AI moderation pipeline to Primary AI only, fix stickerCache executeGet
- Remove Groq and NVIDIA fallback from text moderation pipeline - Remove GROQ_API_KEY, GROQ_MODERATION_*, NVIDIA_NEMOTRON_* config vars - Update source enum: remove 'groq' and 'nvidia' from cache/schema types - Rewrite indonesianTextNormalizer to use Primary AI only (no fallback chain) - Rewrite remote test to test Primary AI only - Fix stickerCache executeGet missing empty params array Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
049fd49737
commit
1bc0b7c7bb
@@ -33,6 +33,7 @@ export async function initStickerCache(): Promise<void> {
|
||||
);
|
||||
const row = await executeGet(
|
||||
"SELECT count(*) as cnt, COALESCE(SUM(size), 0) as total FROM sticker_cache",
|
||||
[],
|
||||
);
|
||||
if (row) {
|
||||
statsCache = {
|
||||
|
||||
@@ -2,23 +2,9 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { config } from "../../src/config";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
axiosPost: vi.fn(),
|
||||
openaiCreate: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("axios", () => ({
|
||||
default: {
|
||||
post: mocks.axiosPost,
|
||||
isAxiosError: (error: unknown) =>
|
||||
Boolean(
|
||||
error &&
|
||||
typeof error === "object" &&
|
||||
"isAxiosError" in error &&
|
||||
(error as { isAxiosError?: unknown }).isAxiosError,
|
||||
),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("openai", () => ({
|
||||
default: class MockOpenAI {
|
||||
chat = {
|
||||
@@ -29,20 +15,13 @@ vi.mock("openai", () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
describe("detectIndonesianBadwords remote fallback", () => {
|
||||
describe("detectIndonesianBadwords primary AI", () => {
|
||||
beforeEach(() => {
|
||||
mocks.axiosPost.mockReset();
|
||||
mocks.openaiCreate.mockReset();
|
||||
config.NVIDIA_NEMOTRON_API_KEY = "test-nemotron-key";
|
||||
config.AI_LLM_API_KEY = "test-primary-key";
|
||||
});
|
||||
|
||||
it("falls back to primary AI after Nemotron rate limits and caches the result", async () => {
|
||||
mocks.axiosPost.mockRejectedValue({
|
||||
isAxiosError: true,
|
||||
response: { status: 429 },
|
||||
message: "Too Many Requests",
|
||||
});
|
||||
it("calls primary AI and caches the result", async () => {
|
||||
mocks.openaiCreate.mockResolvedValue({
|
||||
choices: [
|
||||
{
|
||||
@@ -62,7 +41,17 @@ describe("detectIndonesianBadwords remote fallback", () => {
|
||||
|
||||
expect(first).toEqual(["harassment"]);
|
||||
expect(second).toEqual(["harassment"]);
|
||||
expect(mocks.axiosPost).toHaveBeenCalledTimes(1);
|
||||
expect(mocks.openaiCreate).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("returns empty array when primary AI fails", async () => {
|
||||
mocks.openaiCreate.mockRejectedValue(new Error("API down"));
|
||||
|
||||
const { detectIndonesianBadwords } = await import(
|
||||
"../../src/moderation/indonesianTextNormalizer"
|
||||
);
|
||||
|
||||
const result = await detectIndonesianBadwords("some text");
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,14 +7,10 @@ import {
|
||||
normalizeDiscordCustomEmoji,
|
||||
} from "../../src/moderation/indonesianTextNormalizer";
|
||||
|
||||
const originalNemotronKey = config.NVIDIA_NEMOTRON_API_KEY;
|
||||
const originalPrimaryAiKey = config.AI_LLM_API_KEY;
|
||||
const originalGroqKey = config.GROQ_API_KEY;
|
||||
|
||||
function disableRemoteModeration(): void {
|
||||
config.NVIDIA_NEMOTRON_API_KEY = undefined;
|
||||
config.AI_LLM_API_KEY = undefined;
|
||||
config.GROQ_API_KEY = undefined;
|
||||
}
|
||||
|
||||
disableRemoteModeration();
|
||||
@@ -24,9 +20,7 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
config.NVIDIA_NEMOTRON_API_KEY = originalNemotronKey;
|
||||
config.AI_LLM_API_KEY = originalPrimaryAiKey;
|
||||
config.GROQ_API_KEY = originalGroqKey;
|
||||
});
|
||||
|
||||
describe("normalizeDiscordCustomEmoji", () => {
|
||||
|
||||
Reference in New Issue
Block a user