Files
openclaw/extensions/telegram/src/progress-draft-preview.test.ts
T
Ayaan Zaidi c4b82609b7 fix(agents): compare shell tool names case-insensitively and stop re-parsing tool labels
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.
2026-07-30 19:52:08 +09:00

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);
});
});