feat: detect reply/forward/crosspost in message capture + inject into AI moderation

- Add is_reply, is_forward, is_crosspost, reference_message_id,
  reference_channel_id, reference_guild_id columns to messages table
- Update MessageRecord type with reference fields
- Extract reply/forward/crosspost from Discord message type/flags
- Track reference.type (DEFAULT=reply, FORWARD) and CROSSPOSTED flag
- Inject <reference> XML with parent content into LLM moderation prompt
- Add reply/forward/crosspost rules to moderation prompt rules
- Format context messages with [reply_to], [forward_from], [crosspost]
- Add migration 0009

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
MythEclipse
2026-06-13 00:55:42 +07:00
co-authored by Claude
parent 0ac056dc8a
commit e3249edb6c
9 changed files with 133 additions and 8 deletions
@@ -40,6 +40,26 @@ export function estimateTokens(text: string): number {
return tokens;
}
/**
* Formats reference info for a message (reply/forward/crosspost)
*/
function formatReferenceInfo(msg: MessageRecord): string {
const parts: string[] = [];
if (msg.is_reply && msg.reference_message_id) {
parts.push(`[reply_to: ${msg.reference_message_id}]`);
if (msg.reference_channel_id) {
parts.push(`(reply_channel: ${msg.reference_channel_id})`);
}
}
if (msg.is_forward && msg.reference_message_id) {
parts.push(`[forward_from: ${msg.reference_message_id}]`);
}
if (msg.is_crosspost) {
parts.push(`[crosspost]`);
}
return parts.length > 0 ? ` ${parts.join(" ")}` : "";
}
/**
* Formats a single message for context or target display
*/
@@ -51,7 +71,8 @@ export function formatMessageForPrompt(
const timestamp = formatTimestamp(msg.created_at);
const mediaEvidence = formatMediaEvidenceForPrompt(msg.metadata);
const mediaSuffix = mediaEvidence ? ` ${mediaEvidence}` : "";
return `[${label}] id=${msg.id} time=${timestamp} user=${msg.username}: ${content}${mediaSuffix}`;
const refInfo = formatReferenceInfo(msg);
return `[${label}] id=${msg.id} time=${timestamp} user=${msg.username}: ${content}${mediaSuffix}${refInfo}`;
}
/**