fix: restore live compaction updates in chat

- Show `/compact` command and streamed compaction summary live without refresh
- Handle versioned sync event types so message and part updates are processed
- Route session/message events via indexed lookup to avoid hot-path store scans
This commit is contained in:
Bohdan Triapitsyn
2026-04-05 21:22:17 +03:00
parent dfc61d7671
commit f2f57ca281
3 changed files with 487 additions and 26 deletions
+24 -6
View File
@@ -41,6 +41,23 @@ export type EventPipelineInput = {
onReconnect?: () => void
}
const normalizeEventType = (payload: Event): Event => {
const type = (payload as { type?: unknown }).type
if (typeof type !== "string") {
return payload
}
const match = /^(.*)\.(\d+)$/.exec(type)
if (!match || !match[1]) {
return payload
}
return {
...payload,
type: match[1] as Event["type"],
} as unknown as Event
}
function resolveEventDirectory(event: unknown, payload: Event): string {
const directDirectory =
typeof event === "object" && event !== null && typeof (event as { directory?: unknown }).directory === "string"
@@ -190,21 +207,22 @@ export function createEventPipeline(input: EventPipelineInput) {
if (!payload || typeof payload !== "object" || typeof (payload as { type?: unknown }).type !== "string") {
continue
}
const directory = resolveEventDirectory(event, payload)
const k = key(directory, payload)
const normalizedPayload = normalizeEventType(payload)
const directory = resolveEventDirectory(event, normalizedPayload)
const k = key(directory, normalizedPayload)
if (k) {
const i = coalesced.get(k)
if (i !== undefined) {
queue[i] = { directory, payload }
if (payload.type === "message.part.updated") {
const part = (payload.properties as { part: { messageID: string; id: string } }).part
queue[i] = { directory, payload: normalizedPayload }
if (normalizedPayload.type === "message.part.updated") {
const part = (normalizedPayload.properties as { part: { messageID: string; id: string } }).part
staleDeltas.add(deltaKey(directory, part.messageID, part.id))
}
continue
}
coalesced.set(k, queue.length)
}
queue.push({ directory, payload })
queue.push({ directory, payload: normalizedPayload })
schedule()
if (Date.now() - yielded < STREAM_YIELD_MS) continue