fix: keep stopped and new prompts separate

This commit is contained in:
Federico Jaramillo Martinez
2026-05-13 13:16:18 +02:00
parent cf43c95385
commit e12382cdd2
3 changed files with 30 additions and 1 deletions
@@ -0,0 +1,5 @@
---
"@jmfederico/pi-web": patch
---
Keep a new prompt separate from the stopped prompt after aborting a session turn.
+19
View File
@@ -132,6 +132,25 @@ describe("applyTranscriptEvent", () => {
]);
});
it("does not merge optimistic user messages after an aborted turn", () => {
const messages = [textMessage("user", "stopped prompt")];
expect(applyTranscriptEvent(messages, { type: "message.append", message: { role: "user", content: "new prompt" } })).toEqual([
textMessage("user", "stopped prompt"),
textMessage("user", "new prompt"),
]);
});
it("replaces a new optimistic user message instead of duplicating it after an aborted turn", () => {
let messages: ChatLine[] = [textMessage("user", "stopped prompt")];
messages = applyTranscriptEvent(messages, { type: "message.append", message: { role: "user", content: "new prompt" } }) ?? messages;
expect(applyTranscriptEvent(messages, { type: "message.end", message: { role: "user", content: "new prompt", timestamp: "2026-05-09T12:00:00.000Z" } })).toEqual([
textMessage("user", "stopped prompt"),
{ ...textMessage("user", "new prompt"), meta: { timestamp: "2026-05-09T12:00:00.000Z" } },
]);
});
it("replaces an optimistic user message when the finalized text matches", () => {
const messages = [textMessage("user", "sent prompt")];
+6 -1
View File
@@ -4,7 +4,7 @@ import { appendShellChunk, finalizeShellMessage, shellStartMessage } from "./she
import type { SessionUiEvent } from "./sessionSocket";
export function applyTranscriptEvent(messages: ChatLine[], event: SessionUiEvent): ChatLine[] | undefined {
if (event.type === "message.append") return appendNormalized(messages, event.message);
if (event.type === "message.append") return appendNewMessage(messages, event.message);
if (event.type === "assistant.delta") return appendText(messages, "assistant", event.text);
if (event.type === "assistant.thinking.delta") return appendThinking(messages, event.text);
if (event.type === "tool.start") return appendNormalized(messages, { role: "assistant", content: [{ type: "toolCall", name: event.toolName, arguments: event.args }] });
@@ -72,6 +72,11 @@ function messageText(message: ChatLine): string {
.join("\n\n");
}
function appendNewMessage(messages: ChatLine[], rawMessage: unknown): ChatLine[] {
const lines = normalizeMessage(rawMessage);
return lines.length === 0 ? messages : [...messages, ...lines];
}
function appendNormalized(messages: ChatLine[], rawMessage: unknown): ChatLine[] {
return normalizeMessage(rawMessage).reduce(appendLine, messages);
}