mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-15 23:24:03 -06:00
c4b82609b7
Progress-draft lines recovered their detail by string-slicing the label formatToolAggregate had just rendered, and three sites decided "is this a shell tool?" against lowercase spellings only. The Claude CLI sends "Bash", so those checks missed, the slice returned nothing, and every CLI tool call rendered a line with no detail: Telegram printed the icon twice and the tool-summary payload could no longer merge, leaving a second id-less line per call. formatToolAggregateParts now returns the label with the detail it composed, so a line cannot disagree with its own text, and one predicate owns the shell question across all four sites. Proven live on the Claude CLI backend: two lines with a doubled icon became one.
48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
// Telegram renders progress lines from their structured fields, so a line that
|
|
// arrives without detail falls back to text that already carries its icon.
|
|
import { buildChannelProgressDraftLine } from "openclaw/plugin-sdk/channel-outbound";
|
|
import { describe, expect, it } from "vitest";
|
|
import { renderTelegramProgressDraftPreview } from "./progress-draft-preview.js";
|
|
|
|
function renderToolLine(name: string) {
|
|
const line = buildChannelProgressDraftLine({
|
|
event: "tool",
|
|
toolCallId: "call-1",
|
|
name,
|
|
phase: "start",
|
|
args: { command: "echo alpha", description: "print text" },
|
|
});
|
|
if (!line) {
|
|
throw new Error(`expected a progress line for ${name}`);
|
|
}
|
|
return renderTelegramProgressDraftPreview("Working", [line], false, true).text;
|
|
}
|
|
|
|
describe("renderTelegramProgressDraftPreview", () => {
|
|
it("prints one tool icon per line for every backend spelling", () => {
|
|
for (const name of ["Bash", "bash", "exec"]) {
|
|
const rendered = renderToolLine(name);
|
|
expect(rendered.match(/🛠️/gu) ?? []).toHaveLength(1);
|
|
expect(rendered).toContain("print text");
|
|
}
|
|
});
|
|
|
|
it("keeps the label and detail separate for a non-shell tool", () => {
|
|
const line = buildChannelProgressDraftLine({
|
|
event: "tool",
|
|
toolCallId: "call-1",
|
|
name: "Read",
|
|
phase: "start",
|
|
args: { file_path: "/tmp/x.ts" },
|
|
});
|
|
if (!line) {
|
|
throw new Error("expected a progress line for Read");
|
|
}
|
|
|
|
const rendered = renderTelegramProgressDraftPreview("Working", [line], false, true).text;
|
|
|
|
expect(rendered).toContain("<b>📖 Read</b>");
|
|
expect(rendered.match(/📖/gu) ?? []).toHaveLength(1);
|
|
});
|
|
});
|