fix(channels,sandbox): land hard breakage cluster from reviewed PR bases

Lands reviewed fixes based on #25839 (@pewallin), #25841 (@joshjhall), and #25737/@25713 (@DennisGoldfinger/@peteragility), with additional hardening + regression tests for queue cleanup and shell script safety.

Fixes #25836
Fixes #25840
Fixes #25824
Fixes #25868

Co-authored-by: Peter Wallin <pwallin@gmail.com>
Co-authored-by: Joshua Hall <josh@yaplabs.com>
Co-authored-by: Dennis Goldfinger <dennisgoldfinger@gmail.com>
Co-authored-by: peteragility <peteragility@users.noreply.github.com>
This commit is contained in:
Peter Steinberger
2026-02-24 23:27:12 +00:00
parent 5552f9073f
commit e7a5f9f4d8
11 changed files with 380 additions and 115 deletions

View File

@@ -31,7 +31,10 @@ const deliverDiscordReply = deliveryMocks.deliverDiscordReply;
const createDiscordDraftStream = deliveryMocks.createDiscordDraftStream;
type DispatchInboundParams = {
dispatcher: {
sendBlockReply: (payload: { text?: string }) => boolean | Promise<boolean>;
sendBlockReply: (payload: {
text?: string;
isReasoning?: boolean;
}) => boolean | Promise<boolean>;
sendFinalReply: (payload: { text?: string }) => boolean | Promise<boolean>;
};
replyOptions?: {
@@ -427,9 +430,9 @@ describe("processDiscordMessage draft streaming", () => {
expect(deliverDiscordReply).toHaveBeenCalledTimes(1);
});
it("suppresses block-kind payload delivery to Discord", async () => {
it("suppresses reasoning payload delivery to Discord", async () => {
dispatchInboundMessage.mockImplementationOnce(async (params?: DispatchInboundParams) => {
await params?.dispatcher.sendBlockReply({ text: "thinking..." });
await params?.dispatcher.sendBlockReply({ text: "thinking...", isReasoning: true });
return { queuedFinal: false, counts: { final: 0, tool: 0, block: 1 } };
});
@@ -441,6 +444,20 @@ describe("processDiscordMessage draft streaming", () => {
expect(deliverDiscordReply).not.toHaveBeenCalled();
});
it("delivers non-reasoning block payloads to Discord", async () => {
dispatchInboundMessage.mockImplementationOnce(async (params?: DispatchInboundParams) => {
await params?.dispatcher.sendBlockReply({ text: "hello from block stream" });
return { queuedFinal: false, counts: { final: 0, tool: 0, block: 1 } };
});
const ctx = await createBaseContext({ discordConfig: { streamMode: "off" } });
// oxlint-disable-next-line typescript/no-explicit-any
await processDiscordMessage(ctx as any);
expect(deliverDiscordReply).toHaveBeenCalledTimes(1);
});
it("streams block previews using draft chunking", async () => {
const draftStream = createMockDraftStream();
createDiscordDraftStream.mockReturnValueOnce(draftStream);

View File

@@ -564,9 +564,8 @@ export async function processDiscordMessage(ctx: DiscordMessagePreflightContext)
humanDelay: resolveHumanDelayConfig(cfg, route.agentId),
deliver: async (payload: ReplyPayload, info) => {
const isFinal = info.kind === "final";
if (info.kind === "block") {
// Block payloads carry reasoning/thinking content that should not be
// delivered to external channels. Skip them regardless of streamMode.
if (payload.isReasoning) {
// Reasoning/thinking payloads should not be delivered to Discord.
return;
}
if (draftStream && isFinal) {