fix(discord): replyToMode first behaviour

This commit is contained in:
CHISEN Kaoru
2026-02-07 08:10:58 +00:00
committed by Shadow
parent 4b3c9c9c5a
commit e25ae55879
4 changed files with 46 additions and 9 deletions

View File

@@ -200,14 +200,35 @@ describe("createReplyReferencePlanner", () => {
expect(planner.use()).toBe("parent");
});
it("prefers existing thread id regardless of mode", () => {
it("respects replyToMode off even with existingId", () => {
const planner = createReplyReferencePlanner({
replyToMode: "off",
existingId: "thread-1",
startId: "parent",
});
expect(planner.use()).toBeUndefined();
expect(planner.hasReplied()).toBe(false);
});
it("uses existingId once when mode is first", () => {
const planner = createReplyReferencePlanner({
replyToMode: "first",
existingId: "thread-1",
startId: "parent",
});
expect(planner.use()).toBe("thread-1");
expect(planner.hasReplied()).toBe(true);
expect(planner.use()).toBeUndefined();
});
it("uses existingId on every call when mode is all", () => {
const planner = createReplyReferencePlanner({
replyToMode: "all",
existingId: "thread-1",
startId: "parent",
});
expect(planner.use()).toBe("thread-1");
expect(planner.use()).toBe("thread-1");
});
it("honors allowReference=false", () => {

View File

@@ -32,20 +32,18 @@ export function createReplyReferencePlanner(options: {
if (options.replyToMode === "off") {
return undefined;
}
if (existingId) {
hasReplied = true;
return existingId;
}
if (!startId) {
const id = existingId ?? startId;
if (!id) {
return undefined;
}
if (options.replyToMode === "all") {
hasReplied = true;
return startId;
return id;
}
// "first": only the first reply gets a reference.
if (!hasReplied) {
hasReplied = true;
return startId;
return id;
}
return undefined;
};

View File

@@ -93,7 +93,22 @@ describe("resolveDiscordReplyDeliveryPlan", () => {
threadChannel: { id: "thread" },
createdThreadId: null,
});
// "all" returns the reference on every call.
expect(plan.replyReference.use()).toBe("m1");
expect(plan.replyReference.use()).toBe("m1");
});
it("uses existingId only on first call with replyToMode first inside a thread", () => {
const plan = resolveDiscordReplyDeliveryPlan({
replyTarget: "channel:thread",
replyToMode: "first",
messageId: "m1",
threadChannel: { id: "thread" },
createdThreadId: null,
});
// "first" returns the reference only once.
expect(plan.replyReference.use()).toBe("m1");
expect(plan.replyReference.use()).toBeUndefined();
});
});

View File

@@ -89,8 +89,11 @@ function createSlackReplyReferencePlanner(params: {
messageTs: string | undefined;
hasReplied?: boolean;
}) {
// When already inside a Slack thread, always stay in it regardless of
// replyToMode — thread_ts is required to keep messages in the thread.
const effectiveMode = params.incomingThreadTs ? "all" : params.replyToMode;
return createReplyReferencePlanner({
replyToMode: params.replyToMode,
replyToMode: effectiveMode,
existingId: params.incomingThreadTs,
startId: params.messageTs,
hasReplied: params.hasReplied,