fix(sync): unify live session truth across chat and sidebar

This commit is contained in:
Bohdan Triapitsyn
2026-04-16 19:16:32 +03:00
parent 4c4f24a404
commit ddc1039d1c
15 changed files with 904 additions and 299 deletions
+43
View File
@@ -17,6 +17,7 @@ import { syncDebug } from "./debug"
const SKIP_PARTS = new Set(["patch", "step-start", "step-finish"])
const DELTA_OVERLAP_FIELDS = ["text", "output"] as const
const FINAL_TOOL_STATUSES = new Set(["completed", "error", "aborted", "failed", "timeout", "cancelled"])
type DedupeMetadata = {
__dedupeNextDeltaFields?: string[]
@@ -50,6 +51,45 @@ function getUpdatedDeltaFields(previous: Part, next: Part) {
return dedupeFields
}
function getPartEndTime(part: Part): number | undefined {
const stateEnd = (part as { state?: { time?: { end?: unknown } } }).state?.time?.end
if (typeof stateEnd === "number") {
return stateEnd
}
const timeEnd = (part as { time?: { end?: unknown } }).time?.end
return typeof timeEnd === "number" ? timeEnd : undefined
}
function getToolStatus(part: Part): string | undefined {
if (part.type !== "tool") {
return undefined
}
const status = (part as { state?: { status?: unknown } }).state?.status
return typeof status === "string" ? status : undefined
}
function shouldPreserveExistingPart(previous: Part, next: Part): boolean {
if (previous.type !== "tool" || next.type !== "tool") {
return false
}
const previousStatus = getToolStatus(previous)
const nextStatus = getToolStatus(next)
if (previousStatus && FINAL_TOOL_STATUSES.has(previousStatus) && (!nextStatus || !FINAL_TOOL_STATUSES.has(nextStatus))) {
return true
}
const previousEnd = getPartEndTime(previous)
const nextEnd = getPartEndTime(next)
if (typeof previousEnd === "number" && typeof nextEnd !== "number") {
return true
}
return false
}
// ---------------------------------------------------------------------------
// Global events
// ---------------------------------------------------------------------------
@@ -239,6 +279,9 @@ export function applyDirectoryEvent(
const result = Binary.search(next, part.id, (p) => p.id)
if (result.found) {
const previous = next[result.index]
if (shouldPreserveExistingPart(previous, part)) {
return false
}
const dedupeFields = getUpdatedDeltaFields(previous, part)
next[result.index] = dedupeFields.length > 0
? { ...part, __dedupeNextDeltaFields: dedupeFields } as unknown as Part