fix: keep room events quiet across legacy helpers

This commit is contained in:
Peter Steinberger
2026-05-16 14:34:32 +01:00
parent cdf8121a04
commit d0efaceb97
4 changed files with 48 additions and 2 deletions

View File

@@ -1292,6 +1292,42 @@ describe("processDiscordMessage session routing", () => {
expect(emojis).toContain(DEFAULT_EMOJIS.done);
});
it("suppresses Discord reactions for room events even when status reactions are explicit", async () => {
vi.useFakeTimers();
dispatchInboundMessage.mockImplementationOnce(async (params?: DispatchInboundParams) => {
await params?.replyOptions?.onReasoningStream?.();
await new Promise((resolve) => setTimeout(resolve, 1_000));
return createNoQueuedDispatchResult();
});
const ctx = await createBaseContext({
shouldRequireMention: false,
effectiveWasMentioned: false,
inboundEventKind: "room_event",
ackReactionScope: "all",
cfg: {
messages: {
ackReaction: "👀",
ackReactionScope: "all",
statusReactions: {
enabled: true,
timing: { debounceMs: 0 },
},
},
session: { store: "/tmp/openclaw-discord-process-test-sessions.json" },
},
route: BASE_CHANNEL_ROUTE,
});
const runPromise = runProcessDiscordMessage(ctx);
await vi.advanceTimersByTimeAsync(1_000);
await vi.runAllTimersAsync();
await runPromise;
expect(getLastDispatchReplyOptions()?.sourceReplyDeliveryMode).toBe("message_tool_only");
expect(getReactionEmojis()).toEqual([]);
expect(sendMocks.removeReactionDiscord).not.toHaveBeenCalled();
});
it("uses PluralKit original ids for inbound dedupe while preserving the Discord message id", async () => {
const ctx = await createBaseContext({
canonicalMessageId: "orig-123",

View File

@@ -210,8 +210,10 @@ export async function processDiscordMessage(
});
const removeAckAfterReply = cfg.messages?.removeAckAfterReply ?? false;
const mediaLocalRoots = getAgentScopedMediaLocalRoots(cfg, route.agentId);
const isRoomEvent = ctx.inboundEventKind === "room_event";
const shouldAckReaction = () =>
Boolean(
!isRoomEvent &&
ackReaction &&
shouldAckReactionGate({
scope: ackReactionScope,
@@ -227,6 +229,7 @@ export async function processDiscordMessage(
const shouldSendAckReaction = shouldAckReaction();
const statusReactionsExplicitlyEnabled = cfg.messages?.statusReactions?.enabled === true;
const statusReactionsEnabled =
!isRoomEvent &&
shouldSendAckReaction &&
cfg.messages?.statusReactions?.enabled !== false &&
(!sourceRepliesAreToolOnly || statusReactionsExplicitlyEnabled);

View File

@@ -36,5 +36,6 @@ describe("channel-inbound public compatibility helpers", () => {
const ctx = buildChannelTurnContext(createLegacyTurnParams());
expect(ctx.InboundEventKind).toBe("room_event");
expect(ctx.InboundTurnKind).toBe("room_event");
});
});

View File

@@ -74,19 +74,25 @@ export type BuildChannelTurnContextParams = Omit<
inboundTurnKind?: InboundEventKind;
};
};
export type BuiltChannelTurnContext = BuiltChannelInboundEventContext;
export type BuiltChannelTurnContext = BuiltChannelInboundEventContext & {
InboundTurnKind: InboundEventKind;
};
export function buildChannelTurnContext(
params: BuildChannelTurnContextParams,
): BuiltChannelTurnContext {
const inboundEventKind = params.message.inboundEventKind ?? params.message.inboundTurnKind;
return buildChannelInboundEventContext({
const ctx = buildChannelInboundEventContext({
...params,
message: {
...params.message,
...(inboundEventKind ? { inboundEventKind } : {}),
},
});
return {
...ctx,
InboundTurnKind: ctx.InboundEventKind,
};
}
export const filterChannelTurnSupplementalContext = filterChannelInboundSupplementalContext;