fix: print the running tool once, not twice (#17)

This commit was merged in pull request #17.
This commit is contained in:
2026-10-05 09:49:39 +00:00
parent 26e05dea5b
commit ff99778e5d
7 changed files with 198 additions and 34 deletions
+58
View File
@@ -116,6 +116,64 @@ describe("buildThreadMarkdown", () => {
expect(markdown).not.toContain("Thinking");
});
it("says what a running tool is doing exactly once, before any text arrives", () => {
// The reported bug, from a screenshot: the activity line and the answer
// placeholder both printed "Reading a page", one directly above the other.
const markdown = buildThreadMarkdown([
message({
role: "assistant",
isStreaming: true,
text: "",
activity: { label: "Reading a page", count: 1 },
}),
]);
expect(markdown.match(/Reading a page/g)).toHaveLength(1);
// With nothing to read yet, the activity line is the stand-in, so the cursor
// rides on it rather than sitting on a line of its own.
expect(markdown).toContain(`_Reading a page…_ ${STREAMING_CURSOR}`);
});
it("keeps the activity line once the answer has started arriving", () => {
// The other half of the fix: a tool that starts mid-answer has to stay on
// screen, which is why the line is not just a stand-in for missing text.
const markdown = buildThreadMarkdown([
message({
role: "assistant",
isStreaming: true,
text: "Here is what I found.",
activity: { label: "Reading a page", count: 1 },
}),
]);
expect(markdown).toContain("_Reading a page…_");
expect(markdown).toContain("Here is what I found.");
// And the cursor follows the answer, not the activity line.
expect(markdown).toContain(`Here is what I found. ${STREAMING_CURSOR}`);
expect(markdown).not.toContain(`_Reading a page…_ ${STREAMING_CURSOR}`);
});
it("names a repeat rather than leaving a bare count to be interpreted", () => {
const markdown = buildThreadMarkdown([
message({
role: "assistant",
isStreaming: true,
activity: { label: "Searching the web", count: 2 },
}),
]);
expect(markdown).toContain("the same call again (2)");
});
it("drops the activity line when the message is no longer streaming", () => {
const markdown = buildThreadMarkdown([
message({ role: "assistant", text: "done", activity: { label: "Searching the web", count: 1 } }),
]);
expect(markdown).not.toContain("Searching the web");
expect(markdown).not.toContain(STREAMING_CURSOR);
});
it("shows a placeholder while an answer has no text yet", () => {
expect(buildThreadMarkdown([message({ role: "assistant", isStreaming: true })])).toContain("Thinking");
expect(buildThreadMarkdown([message({ role: "assistant" })])).toContain("No response");