Skip to content

Commit 6a4442e

Browse files
committed
fix(discord): deliver reasoning payloads as Thinking messages for /reasoning on
Remove the blanket isReasoning suppression from beforeDiscordPayloadDelivery and deliverDiscordPayload. The agent already gates reasoning emission via includeReasoning (tied to /reasoning on). When reasoning IS emitted, Discord should deliver it — not silently drop it. Also remove the unused "reasoning payload" member from DiscordReplySkipReason. Fixes #94936
1 parent b3dfa0f commit 6a4442e

3 files changed

Lines changed: 11 additions & 39 deletions

File tree

extensions/discord/src/monitor/message-handler.process.abort-skip.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ describe("formatDiscordReplySkip", () => {
1616
);
1717
});
1818

19-
it("renders the reasoning-payload reason with the same shape", () => {
19+
it("renders the internal-only-payload reason with the same shape", () => {
2020
expect(
2121
formatDiscordReplySkip({
2222
kind: "block",
23-
reason: "reasoning payload",
23+
reason: "internal-only payload",
2424
target: "channel:456",
2525
sessionKey: "agent:friday:discord:channel:456",
2626
}),
2727
).toBe(
28-
"discord block reply skipped (reasoning payload): target=channel:456 session=agent:friday:discord:channel:456",
28+
"discord block reply skipped (internal-only payload): target=channel:456 session=agent:friday:discord:channel:456",
2929
);
3030
});
3131

@@ -43,11 +43,11 @@ describe("formatDiscordReplySkip", () => {
4343
expect(
4444
formatDiscordReplySkip({
4545
kind: "tool",
46-
reason: "reasoning payload",
46+
reason: "internal-only payload",
4747
target: "channel:c1",
4848
sessionKey: "",
4949
}),
50-
).toBe("discord tool reply skipped (reasoning payload): target=channel:c1");
50+
).toBe("discord tool reply skipped (internal-only payload): target=channel:c1");
5151
});
5252

5353
it("preserves the kind discriminant in the message prefix", () => {

extensions/discord/src/monitor/message-handler.process.test.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2639,17 +2639,17 @@ describe("processDiscordMessage draft streaming", () => {
26392639
expect(deliverDiscordReply).not.toHaveBeenCalled();
26402640
});
26412641

2642-
it("suppresses reasoning payload delivery to Discord", async () => {
2642+
it("delivers reasoning block payloads as Thinking messages on Discord", async () => {
26432643
mockDispatchSingleBlockReply({ text: "thinking...", isReasoning: true });
26442644
await processStreamOffDiscordMessage();
26452645

2646-
expect(deliverDiscordReply).not.toHaveBeenCalled();
2646+
expect(deliverDiscordReply).toHaveBeenCalledTimes(1);
26472647
});
26482648

2649-
it("suppresses reasoning-tagged final payload delivery to Discord", async () => {
2649+
it("delivers reasoning-tagged final payload to Discord", async () => {
26502650
dispatchInboundMessage.mockImplementationOnce(async (params?: DispatchInboundParams) => {
26512651
await params?.dispatcher.sendFinalReply({
2652-
text: "Reasoning:\nthis should stay internal",
2652+
text: "Reasoning:\nthis should be visible",
26532653
isReasoning: true,
26542654
});
26552655
return { queuedFinal: true, counts: { final: 1, tool: 0, block: 0 } };
@@ -2661,8 +2661,7 @@ describe("processDiscordMessage draft streaming", () => {
26612661

26622662
await runProcessDiscordMessage(ctx);
26632663

2664-
expect(deliverDiscordReply).not.toHaveBeenCalled();
2665-
expect(editMessageDiscord).not.toHaveBeenCalled();
2664+
expect(deliverDiscordReply).toHaveBeenCalledTimes(1);
26662665
});
26672666

26682667
it("delivers non-reasoning block payloads to Discord", async () => {

extensions/discord/src/monitor/message-handler.process.ts

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,7 @@ function isFallbackOnlyToolWarningFinal(payload: ReplyPayload): boolean {
113113
return !resolveSendableOutboundReplyParts(payload).hasMedia;
114114
}
115115

116-
type DiscordReplySkipReason =
117-
| "aborted before delivery"
118-
| "reasoning payload"
119-
| "internal-only payload";
116+
type DiscordReplySkipReason = "aborted before delivery" | "internal-only payload";
120117

121118
export function formatDiscordReplySkip(params: {
122119
kind: "tool" | "block" | "final";
@@ -609,18 +606,6 @@ async function processDiscordMessageInner(
609606
);
610607
return null;
611608
}
612-
if (payload.isReasoning) {
613-
// Reasoning/thinking payloads should not be delivered to Discord.
614-
logVerbose(
615-
formatDiscordReplySkip({
616-
kind: info.kind,
617-
reason: "reasoning payload",
618-
target: deliverTarget,
619-
sessionKey: ctxPayload.SessionKey,
620-
}),
621-
);
622-
return null;
623-
}
624609
if (draftPreview.draftStream && draftPreview.isProgressMode && info.kind === "block") {
625610
const reply = resolveSendableOutboundReplyParts(payload);
626611
if (!reply.hasMedia && !payload.isError) {
@@ -652,18 +637,6 @@ async function processDiscordMessageInner(
652637
return { visibleReplySent: false };
653638
}
654639
const isFinal = info.kind === "final";
655-
if (payload.isReasoning) {
656-
// Reasoning/thinking payloads should not be delivered to Discord.
657-
logVerbose(
658-
formatDiscordReplySkip({
659-
kind: info.kind,
660-
reason: "reasoning payload",
661-
target: deliverTarget,
662-
sessionKey: ctxPayload.SessionKey,
663-
}),
664-
);
665-
return { visibleReplySent: false };
666-
}
667640
if (
668641
isFinal &&
669642
!options?.allowFallbackOnlyToolWarning &&

0 commit comments

Comments
 (0)