From b4ba6e4eafeed9d0ab07314b35b81d93915c180f Mon Sep 17 00:00:00 2001 From: Shadow Date: Wed, 14 Jan 2026 12:25:20 -0600 Subject: [PATCH] Discord: isolate autoThread thread context (#856) --- CHANGELOG.md | 1 + .../monitor/message-handler.process.ts | 40 +++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df0d3a941..7786bbb8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Telegram: honor `channels.telegram.timeoutSeconds` for grammY API requests. (#863) — thanks @Snaver. - Telegram: split long captions into media + follow-up text messages. (#907) - thanks @jalehman. - Slack: drop Socket Mode events with mismatched `api_app_id`/`team_id`. (#889) — thanks @roshanasingh4. +- Discord: isolate autoThread thread context. (#856) — thanks @davidguttman. ## 2026.1.13 diff --git a/src/discord/monitor/message-handler.process.ts b/src/discord/monitor/message-handler.process.ts index 1bb48f3ed..379014bb5 100644 --- a/src/discord/monitor/message-handler.process.ts +++ b/src/discord/monitor/message-handler.process.ts @@ -132,7 +132,10 @@ export async function processDiscordMessage(ctx: DiscordMessagePreflightContext) body: text, }); let shouldClearHistory = false; - if (!isDirectMessage) { + const shouldIncludeChannelHistory = + !isDirectMessage && + !(isGuildMessage && channelConfig?.autoThread && !threadChannel); + if (shouldIncludeChannelHistory) { combinedBody = buildHistoryContextFromMap({ historyMap: guildHistories, historyKey: message.channelId, @@ -147,10 +150,12 @@ export async function processDiscordMessage(ctx: DiscordMessagePreflightContext) body: `${entry.sender}: ${entry.body} [id:${entry.messageId ?? "unknown"} channel:${message.channelId}]`, }), }); + shouldClearHistory = true; + } + if (!isDirectMessage) { const name = formatDiscordUserTag(author); const id = author.id; combinedBody = `${combinedBody}\n[from: ${name} user id:${id}]`; - shouldClearHistory = true; } const replyContext = resolveReplyContext(message, resolveDiscordMessageText); if (replyContext) { @@ -197,7 +202,7 @@ export async function processDiscordMessage(ctx: DiscordMessagePreflightContext) parentSessionKey, useSuffix: false, }); - const ctxPayload = { + let ctxPayload = { Body: combinedBody, RawBody: baseText, CommandBody: baseText, @@ -254,6 +259,35 @@ export async function processDiscordMessage(ctx: DiscordMessagePreflightContext) replyTarget = replyPlan.replyTarget; const replyReference = replyPlan.replyReference; + // If autoThread created a new thread, ensure we also isolate session context to that thread. + if (createdThreadId && replyTarget === `channel:${createdThreadId}`) { + const threadSessionKey = buildAgentSessionKey({ + agentId: route.agentId, + channel: route.channel, + peer: { kind: "channel", id: createdThreadId }, + }); + const autoParentSessionKey = buildAgentSessionKey({ + agentId: route.agentId, + channel: route.channel, + peer: { kind: "channel", id: message.channelId }, + }); + const autoThreadKeys = resolveThreadSessionKeys({ + baseSessionKey: threadSessionKey, + threadId: createdThreadId, + parentSessionKey: autoParentSessionKey, + useSuffix: false, + }); + + ctxPayload = { + ...ctxPayload, + From: `group:${createdThreadId}`, + To: `channel:${createdThreadId}`, + OriginatingTo: `channel:${createdThreadId}`, + SessionKey: autoThreadKeys.sessionKey, + ParentSessionKey: autoThreadKeys.parentSessionKey, + }; + } + if (isDirectMessage) { const sessionCfg = cfg.session; const storePath = resolveStorePath(sessionCfg?.store, {