fix(ui): keep restored prompts visible during runs (#106001)

This commit is contained in:
Jason (Json)
2026-07-12 23:55:53 -06:00
committed by GitHub
parent e4a17ee160
commit 30cbc1118a
3 changed files with 34 additions and 7 deletions

View File

@@ -2299,6 +2299,11 @@ describeControlUiE2e("Control UI mocked Gateway E2E", () => {
type: "file",
},
]);
await page.getByRole("button", { name: "Stop generating" }).waitFor({ timeout: 10_000 });
await page.locator(".chat-thread").getByText(prompt).waitFor({ timeout: 10_000 });
if (artifactDir) {
await page.screenshot({ path: `${artifactDir}/02-reconnected-active.png`, fullPage: true });
}
await expectRequestCountStable(gateway, "chat.send", 1);
const requestsAfterReconnect = await gateway.getRequests("chat.send");
await gateway.setHistoryMessages([
@@ -2318,7 +2323,7 @@ describeControlUiE2e("Control UI mocked Gateway E2E", () => {
await page.locator("openclaw-connection-banner").waitFor({ state: "detached" });
await expectRequestCountStable(gateway, "chat.send", 1);
if (artifactDir) {
await page.screenshot({ path: `${artifactDir}/02-online-delivered.png`, fullPage: true });
await page.screenshot({ path: `${artifactDir}/03-online-delivered.png`, fullPage: true });
}
if (process.env.OPENCLAW_BEHAVIOR_PROOF === "1") {
process.stdout.write(

View File

@@ -1646,6 +1646,28 @@ describe("buildChatItems", () => {
]);
});
it("keeps restored in-flight sends visible without process-local timing", () => {
const restored = {
id: "restored-send-1",
text: "stay visible across reconnect",
createdAt: 2,
sendAttempts: 1,
};
expect(
messageGroups({
queue: [{ ...restored, sendAttempts: 0, sendState: "waiting-reconnect" }],
}),
).toStrictEqual([]);
for (const sendState of ["waiting-reconnect", "sending"] as const) {
const groups = messageGroups({ queue: [{ ...restored, sendState }] });
expect(groups).toHaveLength(1);
expect(messageRecord(groupAt(groups, 0)).content).toStrictEqual([
{ type: "text", text: "stay visible across reconnect" },
]);
}
});
it("keeps steerable queued sends out of the thread until sending starts", () => {
const queued = {
id: "pending-send-1",

View File

@@ -984,13 +984,13 @@ function sanitizeStreamText(text: string): string {
}
function shouldRenderQueuedSendInThread(item: ChatQueueItem): boolean {
if (typeof item.sendSubmittedAtMs !== "number" || item.sendState === "failed") {
return false;
}
// Page-local submit timing is not persisted; durable attempts keep restored prompts visible.
const sendStarted = typeof item.sendSubmittedAtMs === "number" || (item.sendAttempts ?? 0) > 0;
return (
item.sendState === "waiting-model" ||
item.sendState === "sending" ||
item.sendState === "waiting-reconnect"
sendStarted &&
(item.sendState === "waiting-model" ||
item.sendState === "sending" ||
item.sendState === "waiting-reconnect")
);
}