feat(ai-moderation): add user profile self-learning system

Add user_profiles table, store, and background learner worker
that summarizes user communication style, topics, and personality.

- New user_profiles table (user_id PK, guild_id, profile_summary, last_analyzed_at)
- userProfileStore.ts — CRUD (get/update) following channelCultureStore pattern
- userProfileLearner.ts — background worker: queries 100 recent msgs per user,
  calls LLM for personality summary, updates every 12h
- Inject <user_profile> XML tag per-message in moderation prompt
- Start worker alongside cultureLearner in aiAnalyzer.ts
- Migration 0008 for user_profiles table

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
MythEclipse
2026-06-12 20:11:34 +07:00
co-authored by Claude
parent 6effb51b5d
commit fbc2184c6e
8 changed files with 270 additions and 2 deletions
@@ -605,6 +605,10 @@ export interface BuildSystemPromptOptions {
* Formatted XML block containing the AI-generated channel culture summary.
*/
channelCulture?: string;
/**
* Formatted profile summary for the user being moderated.
*/
userProfile?: string;
}
export function buildSystemPrompt(options: BuildSystemPromptOptions): string {
@@ -615,6 +619,7 @@ export function buildSystemPrompt(options: BuildSystemPromptOptions): string {
correction,
correctedExamples,
channelCulture,
userProfile,
} = options;
// Backward compatibility: if mode is not set but includeMediaInstructions is,
@@ -649,6 +654,11 @@ export function buildSystemPrompt(options: BuildSystemPromptOptions): string {
parts.push(`## Kultur Channel (Pembelajaran AI)\n${channelCulture}`);
}
// User Profile Injection (Learning)
if (userProfile) {
parts.push(`## Profil Pengirim (Pembelajaran AI)\n${userProfile}`);
}
parts.push(
`## Konteks Pengguna\nSetiap pesan mungkin memiliki tag <user_reputation>. Tag ini hanya indikator **referensi**, bukan bukti pelanggaran. Nilai trust_score yang rendah bukan alasan untuk memflag pesan yang bersih. Nilai trust_score yang tinggi bukan alasan untuk mengabaikan pelanggaran nyata. **Setiap pesan harus dinilai berdasarkan isinya sendiri.**`,
);