From f3a973dc9e0ec3e264d99b024c5f45c20ce2cb07 Mon Sep 17 00:00:00 2001 From: Shadow Date: Fri, 2 Jan 2026 14:49:16 -0600 Subject: [PATCH] Discord: include reply context --- src/discord/monitor.ts | 48 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/discord/monitor.ts b/src/discord/monitor.ts index d44cfae7c..7f2e7f8ae 100644 --- a/src/discord/monitor.ts +++ b/src/discord/monitor.ts @@ -172,12 +172,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { const botId = client.user?.id; const wasMentioned = !isDirectMessage && Boolean(botId && message.mentions.has(botId)); - const attachment = message.attachments.first(); - const baseText = - message.content?.trim() || - (attachment ? inferPlaceholder(attachment) : "") || - message.embeds[0]?.description || - ""; + const baseText = resolveDiscordMessageText(message); if (isVerbose()) { logVerbose( `discord: inbound id=${message.id} guild=${message.guild?.id ?? "dm"} channel=${message.channelId} mention=${wasMentioned ? "yes" : "no"} type=${isDirectMessage ? "dm" : isGroupDm ? "group-dm" : "guild"} content=${baseText ? "yes" : "no"}`, @@ -357,6 +352,10 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { combinedBody = `${combinedBody}\n[from: ${name} id:${id}]`; shouldClearHistory = true; } + const replyContext = await resolveReplyContext(message); + if (replyContext) { + combinedBody = `[Replied message - for context]\n${replyContext}\n\n${combinedBody}`; + } const ctxPayload = { Body: combinedBody, @@ -659,6 +658,43 @@ function inferPlaceholder(attachment: import("discord.js").Attachment): string { return ""; } +function resolveDiscordMessageText(message: Message): string { + const attachment = message.attachments.first(); + return ( + message.content?.trim() || + (attachment ? inferPlaceholder(attachment) : "") || + message.embeds[0]?.description || + "" + ); +} + +async function resolveReplyContext(message: Message): Promise { + if (!message.reference?.messageId) return null; + try { + const referenced = await message.fetchReference(); + if (!referenced?.author) return null; + const referencedText = resolveDiscordMessageText(referenced); + if (!referencedText) return null; + const channelType = referenced.channel.type as ChannelType; + const isDirectMessage = channelType === ChannelType.DM; + const fromLabel = isDirectMessage + ? buildDirectLabel(referenced) + : referenced.member?.displayName ?? referenced.author.tag; + const body = `${referencedText}\n[discord message id: ${referenced.id} channel: ${referenced.channelId} from: ${referenced.author.tag} id:${referenced.author.id}]`; + return formatAgentEnvelope({ + surface: "Discord", + from: fromLabel, + timestamp: referenced.createdTimestamp, + body, + }); + } catch (err) { + logVerbose( + `discord: failed to fetch reply context for ${message.id}: ${String(err)}`, + ); + return null; + } +} + function buildDirectLabel(message: import("discord.js").Message) { const username = message.author.tag; return `${username} id:${message.author.id}`;