Preserve idless live assistant continuations

This commit is contained in:
Mohamed Boudra
2026-07-28 00:15:39 +02:00
parent cfb00b3d8b
commit 450a147691
2 changed files with 42 additions and 3 deletions

View File

@@ -586,6 +586,39 @@ describe("processTimelineResponse", () => {
expect(assistants[0]?.timelineCursor).toEqual({ epoch: "epoch-1", seq: 101 });
});
it("keeps a newer live assistant continuation without a provider message ID", () => {
const result = processTimelineResponse({
...baseTimelineInput,
currentTail: [makeAssistantItem("painted replica")],
currentHead: [
{
kind: "assistant_message",
id: "assistant-live",
text: "canonical prefix continuation",
timestamp: new Date(2001),
timelineCursor: { epoch: "epoch-1", seq: 101 },
},
],
isInitializing: true,
hasActiveInitDeferred: true,
hasAuthoritativeBaseline: false,
payload: {
...baseTimelineInput.payload,
direction: "tail",
startCursor: { seq: 61 },
endCursor: { seq: 100 },
entries: [makeTimelineEntry(100, "canonical prefix")],
},
});
const assistants = [...result.tail, ...result.head].filter(
(item) => item.kind === "assistant_message",
);
expect(assistants).toHaveLength(1);
expect(assistants[0]?.text).toBe("canonical prefix continuation");
expect(assistants[0]?.timelineCursor).toEqual({ epoch: "epoch-1", seq: 101 });
});
it("keeps a canonical live user row newer than the bootstrap page", () => {
const live = processAgentStreamEvent({
...baseStreamInput,

View File

@@ -537,13 +537,19 @@ function preserveReplacementHead(
return { tail: reconciledTail, head: unreconciledHead, acknowledgedClientMessageIds: [] };
}
const isNewerContinuation =
liveAssistant.messageId !== undefined &&
liveAssistant.messageId === tailAssistant.messageId &&
const hasNewerCursor =
liveAssistant.timelineCursor !== undefined &&
tailAssistant.timelineCursor !== undefined &&
liveAssistant.timelineCursor.epoch === tailAssistant.timelineCursor.epoch &&
liveAssistant.timelineCursor.seq > tailAssistant.timelineCursor.seq;
const hasMatchingProviderMessageId =
liveAssistant.messageId !== undefined && liveAssistant.messageId === tailAssistant.messageId;
const hasIdlessTextContinuation =
liveAssistant.messageId === undefined &&
tailAssistant.messageId === undefined &&
liveAssistant.text.startsWith(tailAssistant.text);
const isNewerContinuation =
hasNewerCursor && (hasMatchingProviderMessageId || hasIdlessTextContinuation);
if (isNewerContinuation) {
const text = liveAssistant.text.startsWith(tailAssistant.text)
? liveAssistant.text