From c13c39f1214f5acad37eea355fbc41a6df4fff07 Mon Sep 17 00:00:00 2001 From: Clawdbot Date: Tue, 27 Jan 2026 10:17:12 +0100 Subject: [PATCH] fix: exclude native slash commands from onToolResult Native slash commands (e.g. /verbose, /status) should not emit tool summaries. Gate onToolResult behind CommandSource !== 'native' in addition to the existing ChatType !== 'group' check. Add test for native command exclusion. --- .../reply/dispatch-from-config.test.ts | 26 +++++++++++++++++++ src/auto-reply/reply/dispatch-from-config.ts | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/auto-reply/reply/dispatch-from-config.test.ts b/src/auto-reply/reply/dispatch-from-config.test.ts index 8f450cb89..2604038ec 100644 --- a/src/auto-reply/reply/dispatch-from-config.test.ts +++ b/src/auto-reply/reply/dispatch-from-config.test.ts @@ -219,6 +219,32 @@ describe("dispatchReplyFromConfig", () => { expect(dispatcher.sendFinalReply).toHaveBeenCalledTimes(1); }); + it("does not provide onToolResult for native slash commands", async () => { + mocks.tryFastAbortFromMessage.mockResolvedValue({ + handled: false, + aborted: false, + }); + const cfg = {} as ClawdbotConfig; + const dispatcher = createDispatcher(); + const ctx = buildTestCtx({ + Provider: "telegram", + ChatType: "direct", + CommandSource: "native", + }); + + const replyResolver = async ( + _ctx: MsgContext, + opts: GetReplyOptions | undefined, + _cfg: ClawdbotConfig, + ) => { + expect(opts?.onToolResult).toBeUndefined(); + return { text: "hi" } satisfies ReplyPayload; + }; + + await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver }); + expect(dispatcher.sendFinalReply).toHaveBeenCalledTimes(1); + }); + it("fast-aborts without calling the reply resolver", async () => { mocks.tryFastAbortFromMessage.mockResolvedValue({ handled: true, diff --git a/src/auto-reply/reply/dispatch-from-config.ts b/src/auto-reply/reply/dispatch-from-config.ts index 417caad22..c85e654de 100644 --- a/src/auto-reply/reply/dispatch-from-config.ts +++ b/src/auto-reply/reply/dispatch-from-config.ts @@ -277,7 +277,7 @@ export async function dispatchReplyFromConfig(params: { { ...params.replyOptions, onToolResult: - ctx.ChatType !== "group" + ctx.ChatType !== "group" && ctx.CommandSource !== "native" ? (payload: ReplyPayload) => { const run = async () => { const ttsPayload = await maybeApplyTtsToPayload({