diff --git a/CHANGELOG.md b/CHANGELOG.md index 49254248bb8..ab788646d01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ Docs: https://docs.openclaw.ai - Providers/OpenAI: separate API-key and Codex sign-in onboarding groups, and avoid replaying stale OpenAI Responses reasoning blocks after a model route switch. - Browser/config: expand `~` in `browser.executablePath` before Chromium launch, so home-relative custom browser paths no longer fail with `ENOENT`. Fixes #67264. Thanks @Quratulain-bilal. +- Telegram/streaming: hide tool-progress status updates by default while keeping explicit `streaming.preview.toolProgress` opt-in support for edited preview messages. Fixes #71320. Thanks @neeravmakwana. - Discord/subagents: preserve thread-bound completion delivery by keeping the requester-agent announce path primary and falling back to direct thread sends only when the announce produces no visible output. (#71064) Thanks @DolencLuka. - Browser/tool: give Chrome MCP existing-session manage calls a longer default timeout, pass explicit tool timeouts through tab management, and recover stale selected-page MCP sessions instead of forcing a manual reset. Thanks @steipete. - Browser/sandbox: clean up idle tracked tabs opened by primary-agent browser sessions, while preserving active tab reuse and lifecycle cleanup for subagents, cron, and ACP sessions. Fixes #71165. Thanks @dwbutler. diff --git a/docs/channels/telegram.md b/docs/channels/telegram.md index 725ab76284e..efdeb70d648 100644 --- a/docs/channels/telegram.md +++ b/docs/channels/telegram.md @@ -273,7 +273,7 @@ curl "https://api.telegram.org/bot/getUpdates" - `channels.telegram.streaming` is `off | partial | block | progress` (default: `partial`) - `progress` maps to `partial` on Telegram (compat with cross-channel naming) - - `streaming.preview.toolProgress` controls whether tool/progress updates reuse the same edited preview message (default: `true`). Set `false` to keep separate tool/progress messages. + - `streaming.preview.toolProgress` controls whether tool/progress updates reuse the same edited preview message (default: `false`). Set `true` only when visible Telegram progress updates are desired. - legacy `channels.telegram.streamMode` and boolean `streaming` values are auto-mapped For text-only replies: diff --git a/docs/concepts/streaming.md b/docs/concepts/streaming.md index 1317dd7ee77..b61571a0fac 100644 --- a/docs/concepts/streaming.md +++ b/docs/concepts/streaming.md @@ -176,7 +176,8 @@ Preview streaming can also include **tool-progress** updates — short status li Supported surfaces: -- **Discord**, **Slack**, and **Telegram** stream tool-progress into the live preview edit. +- **Discord** and **Slack** stream tool-progress into the live preview edit by default. +- **Telegram** only streams tool-progress into the live preview edit when `streaming.preview.toolProgress` is explicitly enabled. - **Mattermost** already folds tool activity into its single draft preview post (see above). - Tool-progress edits follow the active preview streaming mode; they are skipped when preview streaming is `off` or when block streaming has taken over the message. diff --git a/extensions/telegram/src/bot-message-dispatch.test.ts b/extensions/telegram/src/bot-message-dispatch.test.ts index fa96fcdfdfc..e89f7bff96f 100644 --- a/extensions/telegram/src/bot-message-dispatch.test.ts +++ b/extensions/telegram/src/bot-message-dispatch.test.ts @@ -498,6 +498,51 @@ describe("dispatchTelegramMessage draft streaming", () => { ); }); + it("suppresses Telegram tool progress by default", async () => { + const draftStream = createDraftStream(); + createTelegramDraftStream.mockReturnValue(draftStream); + dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ replyOptions }) => { + await replyOptions?.onToolStart?.({ name: "exec", phase: "start" }); + await replyOptions?.onItemEvent?.({ progressText: "exec ls ~/Desktop" }); + return { queuedFinal: false }; + }); + + await dispatchWithContext({ context: createContext(), streamMode: "partial" }); + + expect(draftStream.update).not.toHaveBeenCalled(); + expect(dispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalledWith( + expect.objectContaining({ + replyOptions: expect.objectContaining({ + suppressDefaultToolProgressMessages: true, + }), + }), + ); + }); + + it("streams Telegram tool progress only when explicitly enabled", async () => { + const draftStream = createDraftStream(); + createTelegramDraftStream.mockReturnValue(draftStream); + dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ replyOptions }) => { + await replyOptions?.onToolStart?.({ name: "exec", phase: "start" }); + return { queuedFinal: false }; + }); + + await dispatchWithContext({ + context: createContext(), + streamMode: "partial", + telegramCfg: { streaming: { preview: { toolProgress: true } } }, + }); + + expect(draftStream.update).toHaveBeenCalledWith("Working…\n• tool: exec"); + expect(dispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalledWith( + expect.objectContaining({ + replyOptions: expect.objectContaining({ + suppressDefaultToolProgressMessages: true, + }), + }), + ); + }); + it("keeps block streaming enabled when account config enables it", async () => { dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ dispatcherOptions }) => { await dispatcherOptions.deliver({ text: "Hello" }, { kind: "final" }); diff --git a/extensions/telegram/src/bot-message-dispatch.ts b/extensions/telegram/src/bot-message-dispatch.ts index 60d4a747398..37a88709c02 100644 --- a/extensions/telegram/src/bot-message-dispatch.ts +++ b/extensions/telegram/src/bot-message-dispatch.ts @@ -388,7 +388,7 @@ export const dispatchTelegramMessage = async ({ const answerLane = lanes.answer; const reasoningLane = lanes.reasoning; const previewToolProgressEnabled = - Boolean(answerLane.stream) && resolveChannelStreamingPreviewToolProgress(telegramCfg); + Boolean(answerLane.stream) && resolveChannelStreamingPreviewToolProgress(telegramCfg, false); let previewToolProgressSuppressed = false; let previewToolProgressLines: string[] = []; const pushPreviewToolProgress = (line?: string) => { @@ -966,7 +966,7 @@ export const dispatchTelegramMessage = async ({ previewToolProgressLines = []; }) : undefined, - suppressDefaultToolProgressMessages: previewToolProgressEnabled ? true : undefined, + suppressDefaultToolProgressMessages: true, onToolStart: async (payload) => { const toolName = payload.name?.trim(); if (statusReactionController && toolName) { diff --git a/extensions/telegram/src/config-ui-hints.ts b/extensions/telegram/src/config-ui-hints.ts index 6727726e9ee..f8b1b2879f4 100644 --- a/extensions/telegram/src/config-ui-hints.ts +++ b/extensions/telegram/src/config-ui-hints.ts @@ -63,7 +63,7 @@ export const telegramChannelConfigUiHints = { }, "streaming.preview.toolProgress": { label: "Telegram Draft Tool Progress", - help: "Show tool/progress activity in the live draft preview message (default: true). Set false to keep tool updates as separate messages.", + help: "Show tool/progress activity in the live draft preview message (default: false). Enable only when visible Telegram progress updates are desired.", }, "retry.attempts": { label: "Telegram Retry Attempts",