refactor: unify threading contexts
This commit is contained in:
@@ -77,4 +77,72 @@ describe("slack prepareSlackMessage inbound contract", () => {
|
||||
expect(prepared).toBeTruthy();
|
||||
expectInboundContextContract(prepared!.ctxPayload as any);
|
||||
});
|
||||
|
||||
it("sets MessageThreadId for top-level messages when replyToMode=all", async () => {
|
||||
const slackCtx = createSlackMonitorContext({
|
||||
cfg: {
|
||||
channels: { slack: { enabled: true, replyToMode: "all" } },
|
||||
} as ClawdbotConfig,
|
||||
accountId: "default",
|
||||
botToken: "token",
|
||||
app: { client: {} } as App,
|
||||
runtime: {} as RuntimeEnv,
|
||||
botUserId: "B1",
|
||||
teamId: "T1",
|
||||
apiAppId: "A1",
|
||||
historyLimit: 0,
|
||||
sessionScope: "per-sender",
|
||||
mainKey: "main",
|
||||
dmEnabled: true,
|
||||
dmPolicy: "open",
|
||||
allowFrom: [],
|
||||
groupDmEnabled: true,
|
||||
groupDmChannels: [],
|
||||
defaultRequireMention: true,
|
||||
groupPolicy: "open",
|
||||
useAccessGroups: false,
|
||||
reactionMode: "off",
|
||||
reactionAllowlist: [],
|
||||
replyToMode: "all",
|
||||
threadHistoryScope: "thread",
|
||||
threadInheritParent: false,
|
||||
slashCommand: {
|
||||
enabled: false,
|
||||
name: "clawd",
|
||||
sessionPrefix: "slack:slash",
|
||||
ephemeral: true,
|
||||
},
|
||||
textLimit: 4000,
|
||||
ackReactionScope: "group-mentions",
|
||||
mediaMaxBytes: 1024,
|
||||
removeAckAfterReply: false,
|
||||
});
|
||||
slackCtx.resolveUserName = async () => ({ name: "Alice" }) as any;
|
||||
|
||||
const account: ResolvedSlackAccount = {
|
||||
accountId: "default",
|
||||
enabled: true,
|
||||
botTokenSource: "config",
|
||||
appTokenSource: "config",
|
||||
config: { replyToMode: "all" },
|
||||
};
|
||||
|
||||
const message: SlackMessageEvent = {
|
||||
channel: "D123",
|
||||
channel_type: "im",
|
||||
user: "U1",
|
||||
text: "hi",
|
||||
ts: "1.000",
|
||||
} as SlackMessageEvent;
|
||||
|
||||
const prepared = await prepareSlackMessage({
|
||||
ctx: slackCtx,
|
||||
account,
|
||||
message,
|
||||
opts: { source: "message" },
|
||||
});
|
||||
|
||||
expect(prepared).toBeTruthy();
|
||||
expect(prepared!.ctxPayload.MessageThreadId).toBe("1.000");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -33,6 +33,7 @@ import type { ResolvedSlackAccount } from "../../accounts.js";
|
||||
import { reactSlackMessage } from "../../actions.js";
|
||||
import { sendMessageSlack } from "../../send.js";
|
||||
import type { SlackMessageEvent } from "../../types.js";
|
||||
import { resolveSlackThreadContext } from "../../threading.js";
|
||||
|
||||
import { resolveSlackAllowListMatch, resolveSlackUserAllowed } from "../allow-list.js";
|
||||
import { resolveSlackEffectiveAllowFrom } from "../auth.js";
|
||||
@@ -188,9 +189,9 @@ export async function prepareSlackMessage(params: {
|
||||
});
|
||||
|
||||
const baseSessionKey = route.sessionKey;
|
||||
const threadTs = message.thread_ts;
|
||||
const hasThreadTs = typeof threadTs === "string" && threadTs.length > 0;
|
||||
const isThreadReply = hasThreadTs && (threadTs !== message.ts || Boolean(message.parent_user_id));
|
||||
const threadContext = resolveSlackThreadContext({ message, replyToMode: ctx.replyToMode });
|
||||
const threadTs = threadContext.incomingThreadTs;
|
||||
const isThreadReply = threadContext.isThreadReply;
|
||||
const threadKeys = resolveThreadSessionKeys({
|
||||
baseSessionKey,
|
||||
threadId: isThreadReply ? threadTs : undefined,
|
||||
@@ -474,9 +475,9 @@ export async function prepareSlackMessage(params: {
|
||||
Provider: "slack" as const,
|
||||
Surface: "slack" as const,
|
||||
MessageSid: message.ts,
|
||||
ReplyToId: message.thread_ts ?? message.ts,
|
||||
// Preserve thread context for routed tool notifications (thread replies only).
|
||||
MessageThreadId: isThreadReply ? threadTs : undefined,
|
||||
ReplyToId: threadContext.replyToId,
|
||||
// Preserve thread context for routed tool notifications.
|
||||
MessageThreadId: threadContext.messageThreadId,
|
||||
ParentSessionKey: threadKeys.parentSessionKey,
|
||||
ThreadStarterBody: threadStarterBody,
|
||||
ThreadLabel: threadLabel,
|
||||
|
||||
Reference in New Issue
Block a user