fix(channels): balance compact progress markdown · openclaw/openclaw@8846fe0
vincentkoc
·
2026-05-04
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -66,6 +66,7 @@ Docs: https://docs.openclaw.ai
|
66 | 66 | - Agents/messaging: deliver distinct final commentary after same-target `message` tool sends while still deduping text/media already sent by the tool, so short closing remarks are no longer silently dropped. Fixes #76915. Thanks @hclsys. |
67 | 67 | - Agents/messaging: preserve string thread IDs when matching message-tool reply dedupe routes, avoiding precision loss on numeric-looking topic IDs before channel plugin comparison. Thanks @vincentkoc. |
68 | 68 | - Channels/streaming: honor `agents.defaults.toolProgressDetail: "raw"` in Slack, Discord, Telegram, Matrix, and Microsoft Teams progress drafts, so tool-start lines include raw command/detail output when debugging. Thanks @vincentkoc. |
| 69 | +- Channels/streaming: strip unmatched inline-code backticks from compacted raw progress draft lines, avoiding stray markdown markers after long command details are shortened. Thanks @vincentkoc. |
69 | 70 | - Discord/Slack/Mattermost: align draft preview tool-progress config help with the runtime behavior that hides interim tool updates when `streaming.preview.toolProgress` is false. Thanks @vincentkoc. |
70 | 71 | - Feishu: use the shared channel progress formatter for streaming-card tool status lines, including raw command/detail output and message-tool filtering. Thanks @vincentkoc. |
71 | 72 | - Mattermost: use the shared progress draft formatter for tool status previews, including raw command/detail output when `agents.defaults.toolProgressDetail: "raw"` is enabled. Thanks @vincentkoc. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -196,6 +196,28 @@ describe("channel-streaming", () => {
|
196 | 196 | ).toBe(`Shelling\n• \`${"x".repeat(71)}…\``); |
197 | 197 | }); |
198 | 198 | |
| 199 | +it("keeps compacted raw progress lines from leaking unmatched markdown backticks", () => { |
| 200 | +const line = formatChannelProgressDraftLine( |
| 201 | +{ |
| 202 | +event: "tool", |
| 203 | +name: "exec", |
| 204 | +args: { |
| 205 | +command: |
| 206 | +"node scripts/check-something-with-a-very-long-path /tmp/openclaw/some/really/deep/path/that/keeps/going/and/going/index.ts --flag value", |
| 207 | +}, |
| 208 | +}, |
| 209 | +{ detailMode: "raw" }, |
| 210 | +); |
| 211 | + |
| 212 | +const text = formatChannelProgressDraftText({ |
| 213 | +entry: { streaming: { progress: { label: "Shelling" } } }, |
| 214 | +lines: [line ?? ""], |
| 215 | +}); |
| 216 | + |
| 217 | +expect(text).toBe("Shelling\n🛠️ Exec: run node script…that/keeps/going/and/going/index…"); |
| 218 | +expect(text.match(/`/g) ?? []).toHaveLength(0); |
| 219 | +}); |
| 220 | + |
199 | 221 | it("formats progress draft lines with shared tool display labels", () => { |
200 | 222 | expect( |
201 | 223 | formatChannelProgressDraftLine({ |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -558,6 +558,11 @@ function compactProgressLineDetail(detail: string, maxChars: number): string {
|
558 | 558 | return `${start}…${chars.slice(-keepEnd).join("").trimStart()}`; |
559 | 559 | } |
560 | 560 | |
| 561 | +function removeUnbalancedInlineBackticks(value: string): string { |
| 562 | +const backtickCount = Array.from(value).filter((char) => char === "`").length; |
| 563 | +return backtickCount % 2 === 1 ? value.replaceAll("`", "") : value; |
| 564 | +} |
| 565 | + |
561 | 566 | function compactChannelProgressDraftLine(line: string, maxChars: number): string { |
562 | 567 | const normalized = line.replace(/\s+/g, " ").trim(); |
563 | 568 | if (!normalized) { |
@@ -577,11 +582,15 @@ function compactChannelProgressDraftLine(line: string, maxChars: number): string
|
577 | 582 | const prefixChars = Array.from(prefix).length; |
578 | 583 | const detailLimit = maxChars - prefixChars; |
579 | 584 | if (detailLimit >= 8) { |
580 | | -return `${prefix}${compactProgressLineDetail(normalized.slice(splitIndex + 2), detailLimit)}`; |
| 585 | +return removeUnbalancedInlineBackticks( |
| 586 | +`${prefix}${compactProgressLineDetail(normalized.slice(splitIndex + 2), detailLimit)}`, |
| 587 | +); |
581 | 588 | } |
582 | 589 | } |
583 | 590 | |
584 | | -return `${sliceCodePoints(normalized, 0, maxChars - 1).trimEnd()}…`; |
| 591 | +return removeUnbalancedInlineBackticks( |
| 592 | +`${sliceCodePoints(normalized, 0, maxChars - 1).trimEnd()}…`, |
| 593 | +); |
585 | 594 | } |
586 | 595 | |
587 | 596 | export function formatChannelProgressDraftText(params: { |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。