feat(telegram): add configurable silent error replies (#19776)

Port and complete #19776 on top of the current Telegram extension layout.

Adds a default-off `channels.telegram.silentErrorReplies` setting. When enabled, Telegram bot replies marked as errors are delivered silently across the regular bot reply flow, native/slash command replies, and fallback sends.

Thanks @auspic7 

Co-authored-by: Myeongwon Choi <36367286+auspic7@users.noreply.github.com>
Co-authored-by: ImLukeF <92253590+ImLukeF@users.noreply.github.com>
This commit is contained in:
Myeongwon Choi
2026-03-16 20:18:34 +09:00
committed by GitHub
parent fdfa98cda8
commit 6a8f5bc12f
13 changed files with 211 additions and 2 deletions

View File

@@ -298,6 +298,43 @@ describe("dispatchTelegramMessage draft streaming", () => {
);
});
it("sends error replies silently when silentErrorReplies is enabled", async () => {
dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ dispatcherOptions }) => {
await dispatcherOptions.deliver({ text: "oops", isError: true }, { kind: "final" });
return { queuedFinal: true };
});
deliverReplies.mockResolvedValue({ delivered: true });
await dispatchWithContext({
context: createContext(),
telegramCfg: { silentErrorReplies: true },
});
expect(deliverReplies).toHaveBeenCalledWith(
expect.objectContaining({
silent: true,
replies: [expect.objectContaining({ isError: true })],
}),
);
});
it("keeps error replies notifying by default", async () => {
dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ dispatcherOptions }) => {
await dispatcherOptions.deliver({ text: "oops", isError: true }, { kind: "final" });
return { queuedFinal: true };
});
deliverReplies.mockResolvedValue({ delivered: true });
await dispatchWithContext({ context: createContext() });
expect(deliverReplies).toHaveBeenCalledWith(
expect.objectContaining({
silent: false,
replies: [expect.objectContaining({ isError: true })],
}),
);
});
it("keeps block streaming enabled when session reasoning level is on", async () => {
loadSessionStore.mockReturnValue({
s1: { reasoningLevel: "on" },