refactor(ai-moderation): fix all 8 issues per review

- #2: Duplikasi contoh → single-source ALL_EXAMPLES array + formatExamples()
- #3: Hierarki evasion → Level 1 (Wajib Flag) vs Level 2 (Pilih Clean)
- #4: Dead code → remove duplicate PromptMode, cleanup
- #5: Sanitasi AI content → sanitizeAiContent() + CDATA wrapping for
      channel culture & user profile (prevents prompt injection)
- #6: Contoh personality → match actual XML format (<message>,
      <user_profile>, <content> tags instead of plain text)
- #7: Contoh invite link → example #29 added
- #8: 'Deskripsi selesai.' removed from stickerPrompt.ts
- Image analysis balance: teks = gambar (equal weight), no more bias
- Removed LGBT exclusion from SYSTEM_RULES
- Removed all template fallback language, enforce specific descriptions
This commit is contained in:
MythEclipse
2026-06-21 22:14:59 +07:00
parent 04f2862abc
commit dc62b283c0
3 changed files with 425 additions and 328 deletions
@@ -13,7 +13,7 @@ import type {
} from "../message-capture/types.js";
import { getChannelCulture } from "./channelCultureStore.js";
import { llmChat, llmVision } from "./llmClient.js";
import { buildSystemPrompt as buildSystemPromptModular } from "./moderationPrompt.js";
import { buildSystemPrompt as buildSystemPromptModular, sanitizeAiContent } from "./moderationPrompt.js";
import { logModerationAnalysis, logModerationError } from "./responseLogger.js";
import {
getStickerFromCache,
@@ -830,7 +830,7 @@ async function runTextOnlyBatch(
userProfiles.set(
msg.user_id,
profile
? `<user_profile>${profile.profile_summary}</user_profile>`
? `<user_profile>${sanitizeAiContent(profile.profile_summary)}</user_profile>`
: "",
);
}
@@ -1521,7 +1521,7 @@ export async function runSimpleTextFallback(
try {
const profile = await getUserProfile(message.user_id);
if (profile?.profile_summary) {
userProfileCtx = `\n\nProfil pengirim pesan:\n${profile.profile_summary}\n`;
userProfileCtx = `\n\nProfil pengirim pesan:\n${sanitizeAiContent(profile.profile_summary, 2000, false)}\n`;
}
} catch {
// Profile fetch failure is non-fatal — proceed without context