Keep command text in progress drafts (#93711)

* Keep command text in progress drafts

* test(channels): align successful progress drafts

---------

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
This commit is contained in:
keshavbotagent
2026-06-17 00:11:59 +05:30
committed by GitHub
parent ae9ae560e9
commit 257d540297
8 changed files with 72 additions and 17 deletions

View File

@@ -3057,8 +3057,8 @@ describe("processDiscordMessage draft streaming", () => {
await runProcessDiscordMessage(ctx);
const lastUpdate = draftStream.update.mock.calls.at(-1)?.[0];
expect(lastUpdate).toContain("completed");
expect(lastUpdate).not.toContain("install dependencies");
expect(lastUpdate).toContain("install dependencies");
expect(lastUpdate).not.toContain("completed");
});
it("drops later tool warning finals after progress preview final replies", async () => {

View File

@@ -134,7 +134,7 @@ describe("buildSlackProgressDraftBlocks", () => {
],
});
expectLegacyLineBlock(blocks?.[1], "• *Exec*", "command finished · completed");
expectLegacyLineBlock(blocks?.[1], "• *Exec*", "command finished");
expectLegacyLineBlock(blocks?.[2], "• *Exec*", "command failed · exit 1");
});
@@ -243,7 +243,7 @@ describe("native Slack progress stream chunks", () => {
}),
).toEqual([
planUpdate("Shelling..."),
taskUpdate("exec_1", "Exec — command finished · completed", "complete"),
taskUpdate("exec_1", "Exec — command finished", "complete"),
taskUpdate("exec_2", "Exec — command failed · exit 1", "error"),
]);
});

View File

@@ -59,7 +59,12 @@ function compactChunkText(value: string): string {
}
function lineDetailParts(line: ChannelProgressDraftLine): string[] {
return [line.detail, line.status && !line.detail?.includes(line.status) ? line.status : undefined]
return [
line.detail,
line.status && line.status !== "completed" && !line.detail?.includes(line.status)
? line.status
: undefined,
]
.map((part) => part?.trim())
.filter((part): part is string => Boolean(part));
}

View File

@@ -2625,10 +2625,10 @@ describe("dispatchTelegramMessage draft streaming", () => {
});
const lastUpdate = answerDraftStream.updatePreview.mock.calls.at(-1)?.[0];
expect(lastUpdate?.text).toContain("completed");
expect(lastUpdate?.text).toContain("install dependencies");
expect(lastUpdate?.text).not.toContain("completed");
expect(lastUpdate?.richMessage).toEqual({
html: "<b>Shelling</b><br><b>🛠️ Exec</b> <code>install dependencies</code> <i>completed</i>",
html: "<b>Shelling</b><br><b>🛠️ Exec</b> <code>install dependencies</code>",
skip_entity_detection: true,
});
});

View File

@@ -458,7 +458,7 @@ function renderTelegramProgressLine(line: ChannelProgressDraftCompositorLine): s
parts.push(renderTelegramProgressStringLine(text));
}
}
if (line.status && line.status !== line.detail) {
if (line.status && line.status !== "completed" && line.status !== line.detail) {
parts.push(`<i>${escapeTelegramProgressHtml(line.status)}</i>`);
}
return parts.join(" ");

View File

@@ -2,6 +2,44 @@ import { describe, expect, it } from "vitest";
import { buildChannelProgressDraftLine } from "./streaming.js";
describe("buildChannelProgressDraftLine", () => {
it("omits generic completed status from successful command output with title", () => {
const line = buildChannelProgressDraftLine(
{
event: "command-output",
toolCallId: "exec-1",
phase: "end",
title: "pwd",
name: "exec",
exitCode: 0,
},
{ commandText: "raw" },
);
expect(line).toMatchObject({
kind: "command-output",
id: "exec-1",
text: "🛠️ pwd",
detail: "pwd",
status: "completed",
});
});
it("uses the tool label when successful command output has no title", () => {
const line = buildChannelProgressDraftLine({
event: "command-output",
phase: "end",
name: "exec",
exitCode: 0,
});
expect(line).toMatchObject({
kind: "command-output",
text: "🛠️ Exec",
status: "completed",
});
expect(line?.detail).toBeUndefined();
});
it("keeps command status and title in raw command progress lines", () => {
const line = buildChannelProgressDraftLine(
{

View File

@@ -443,6 +443,9 @@ function buildCommandOutputProgressLine(
if (!line || !status) {
return line;
}
if (status === "completed") {
return line;
}
if (!line.detail || line.detail === status) {
const statusLine = {
...line,
@@ -1055,11 +1058,14 @@ function getProgressDraftLineText(line: string | ChannelProgressDraftLine): stri
const label = line.label.trim();
const detail = line.detail?.trim();
const status = line.status?.trim();
const displayStatus = status === "completed" ? undefined : status;
if (detail) {
const compactCommandLine =
line.toolName === "exec" || line.toolName === "bash" || line.toolName === "shell";
if (line.kind === "command-output" && status && detail !== status) {
const outputDetail = detail.startsWith(`${status};`) ? detail : `${status}; ${detail}`;
if (line.kind === "command-output" && displayStatus && detail !== displayStatus) {
const outputDetail = detail.startsWith(`${displayStatus};`)
? detail
: `${displayStatus}; ${detail}`;
if (compactCommandLine) {
return `${prefix}${outputDetail}`;
}
@@ -1070,11 +1076,11 @@ function getProgressDraftLineText(line: string | ChannelProgressDraftLine): stri
}
return `${prefix}${detail}`;
}
if (status) {
if (displayStatus) {
if (label) {
return `${prefix}${label}: ${status}`;
return `${prefix}${label}: ${displayStatus}`;
}
return `${prefix}${status}`;
return `${prefix}${displayStatus}`;
}
const text = line.text.trim();
if (!icon && text && text !== label) {

View File

@@ -601,10 +601,16 @@ describe("channel-streaming", () => {
expect(updated[0]).toMatchObject({
id: "tool:call-1-output",
kind: "command-output",
status: "completed",
detail: "install dependencies",
text: "🛠️ completed; install dependencies",
status: "completed",
text: "🛠️ install dependencies",
});
expect(
formatChannelProgressDraftText({
lines: updated,
entry: { streaming: { progress: { label: false } } },
}),
).toBe("🛠️ install dependencies");
const recoveredItemLine = buildChannelProgressDraftLine({
event: "item",
@@ -634,9 +640,9 @@ describe("channel-streaming", () => {
{
id: "command-2",
kind: "command-output",
status: "completed",
detail: "install dependencies failed",
text: "🛠️ completed; install dependencies failed",
status: "completed",
text: "🛠️ install dependencies failed",
},
]);
});