fix(telegram): harden progress preview rendering · openclaw/openclaw@e54a37a
neeravmakwan
·
2026-04-25
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -7,6 +7,7 @@ import {
|
7 | 7 | createSequencedTestDraftStream, |
8 | 8 | createTestDraftStream, |
9 | 9 | } from "./draft-stream.test-helpers.js"; |
| 10 | +import { renderTelegramHtmlText } from "./format.js"; |
10 | 11 | |
11 | 12 | type DispatchReplyWithBufferedBlockDispatcherArgs = Parameters< |
12 | 13 | TelegramBotDeps["dispatchReplyWithBufferedBlockDispatcher"] |
@@ -524,6 +525,7 @@ describe("dispatchTelegramMessage draft streaming", () => {
|
524 | 525 | createTelegramDraftStream.mockReturnValue(draftStream); |
525 | 526 | dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ replyOptions }) => { |
526 | 527 | await replyOptions?.onToolStart?.({ name: "exec", phase: "start" }); |
| 528 | +await replyOptions?.onItemEvent?.({ progressText: "read [label](tg://user?id=123)" }); |
527 | 529 | return { queuedFinal: false }; |
528 | 530 | }); |
529 | 531 | |
@@ -533,7 +535,9 @@ describe("dispatchTelegramMessage draft streaming", () => {
|
533 | 535 | telegramCfg: { streaming: { preview: { toolProgress: true } } }, |
534 | 536 | }); |
535 | 537 | |
536 | | -expect(draftStream.update).toHaveBeenCalledWith("Working…\n• tool: exec"); |
| 538 | +const lastPreviewText = draftStream.update.mock.calls.at(-1)?.[0]; |
| 539 | +expect(lastPreviewText).toBe("Working…\n• `tool: exec`\n• `read [label](tg://user?id=123)`"); |
| 540 | +expect(renderTelegramHtmlText(lastPreviewText ?? "")).not.toContain("<a "); |
537 | 541 | expect(dispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalledWith( |
538 | 542 | expect.objectContaining({ |
539 | 543 | replyOptions: expect.objectContaining({ |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -207,6 +207,15 @@ function resolveTelegramReasoningLevel(params: {
|
207 | 207 | return "off"; |
208 | 208 | } |
209 | 209 | |
| 210 | +function formatProgressAsMarkdownCode(text: string): string { |
| 211 | +const maxBacktickRun = Math.max( |
| 212 | +0, |
| 213 | + ...Array.from(text.matchAll(/`+/g), (match) => match[0].length), |
| 214 | +); |
| 215 | +const fence = "`".repeat(maxBacktickRun + 1); |
| 216 | +return `${fence}${text}${fence}`; |
| 217 | +} |
| 218 | + |
210 | 219 | export const dispatchTelegramMessage = async ({ |
211 | 220 | context, |
212 | 221 | bot, |
@@ -404,9 +413,10 @@ export const dispatchTelegramMessage = async ({
|
404 | 413 | return; |
405 | 414 | } |
406 | 415 | previewToolProgressLines = [...previewToolProgressLines, normalized].slice(-8); |
407 | | -const previewText = ["Working…", ...previewToolProgressLines.map((entry) => `• ${entry}`)].join( |
408 | | -"\n", |
409 | | -); |
| 416 | +const previewText = [ |
| 417 | +"Working…", |
| 418 | + ...previewToolProgressLines.map((entry) => `• ${formatProgressAsMarkdownCode(entry)}`), |
| 419 | +].join("\n"); |
410 | 420 | answerLane.lastPartialText = previewText; |
411 | 421 | answerLane.stream.update(previewText); |
412 | 422 | }; |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -1636,7 +1636,7 @@ describe("dispatchReplyFromConfig", () => {
|
1636 | 1636 | expect(dispatcher.sendFinalReply).toHaveBeenCalledWith({ text: "done" }); |
1637 | 1637 | }); |
1638 | 1638 | |
1639 | | -it("delivers deterministic exec approval tool payloads for native commands", async () => { |
| 1639 | +it("delivers deterministic exec approval tool payloads for native commands with progress suppression", async () => { |
1640 | 1640 | setNoAbort(); |
1641 | 1641 | const cfg = emptyConfig; |
1642 | 1642 | const dispatcher = createDispatcher(); |
@@ -1663,7 +1663,13 @@ describe("dispatchReplyFromConfig", () => {
|
1663 | 1663 | return { text: "NO_REPLY" } satisfies ReplyPayload; |
1664 | 1664 | }; |
1665 | 1665 | |
1666 | | -await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver }); |
| 1666 | +await dispatchReplyFromConfig({ |
| 1667 | + ctx, |
| 1668 | + cfg, |
| 1669 | + dispatcher, |
| 1670 | + replyResolver, |
| 1671 | +replyOptions: { suppressDefaultToolProgressMessages: true }, |
| 1672 | +}); |
1667 | 1673 | |
1668 | 1674 | expect(dispatcher.sendToolResult).toHaveBeenCalledTimes(1); |
1669 | 1675 | expect(firstToolResultPayload(dispatcher)).toEqual( |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。