fix(vscode): bound sync filter state

This commit is contained in:
marius-kilocode
2026-08-25 14:41:38 +02:00
parent b0100195f5
commit 45695e6190
4 changed files with 142 additions and 5 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---
Prevent duplicate-event tracking from suppressing delayed sync events after reconnects or high event bursts.
@@ -96,7 +96,6 @@ export class KiloConnectionService {
private remoteService: import("../RemoteStatusService").RemoteStatusService | null = null
private readonly eventListeners: Set<SSEEventListener> = new Set()
private readonly duplicateEvent = createDuplicateEventFilter()
private readonly stateListeners: Set<StateListener> = new Set()
private readonly notificationDismissListeners: Set<NotificationDismissListener> = new Set()
private readonly languageChangeListeners: Set<LanguageChangeListener> = new Set()
@@ -821,6 +820,7 @@ export class KiloConnectionService {
},
})
const sse = new SdkSSEAdapter(client)
const duplicateEvent = createDuplicateEventFilter()
this.client = client
this.sseClient = sse
@@ -839,7 +839,7 @@ export class KiloConnectionService {
sse.onEvent((event, directory) => {
if (this.sseClient !== sse) return
// EventV2Bridge also emits these durable compatibility envelopes after their normal live events.
if (this.duplicateEvent(event)) return
if (duplicateEvent(event)) return
this.handlePermissionEvent(event, directory)
this.handleQuestionEvent(event, directory)
for (const listener of this.eventListeners) {
@@ -24,8 +24,7 @@ export function createDuplicateEventFilter() {
}
if (duplicateLiveEvents.has(event.type)) {
seen.add(event.id)
if (seen.size > DUPLICATE_EVENT_LIMIT) seen.delete(seen.values().next().value!)
if (seen.size < DUPLICATE_EVENT_LIMIT) seen.add(event.id)
}
return false
}
@@ -173,7 +173,7 @@ describe("resolveEventSessionId", () => {
})
})
describe("isDuplicateSyncEvent", () => {
describe("createDuplicateEventFilter", () => {
it("drops a compatibility envelope only after its live event", () => {
const filter = createDuplicateEventFilter()
const live = {
@@ -233,4 +233,137 @@ describe("isDuplicateSyncEvent", () => {
),
).toBe(false)
})
it("does not evict pending live events when the cap is reached", () => {
const filter = createDuplicateEventFilter()
for (let index = 0; index < 1024; index++) {
expect(
filter({
id: `live-${index}`,
type: "message.part.updated",
properties: { sessionID: "s6", part, delta: "x" },
}),
).toBe(false)
}
expect(
filter(
sync({
type: "sync",
name: "message.part.updated.1",
id: "live-0",
seq: 8,
aggregateID: "s6",
data: { sessionID: "s6", part, time: 0 },
}),
),
).toBe(true)
expect(
filter({
id: "live-1024",
type: "message.part.updated",
properties: { sessionID: "s6", part, delta: "x" },
}),
).toBe(false)
expect(
filter(
sync({
type: "sync",
name: "message.part.updated.1",
id: "live-1024",
seq: 9,
aggregateID: "s6",
data: { sessionID: "s6", part, time: 0 },
}),
),
).toBe(true)
})
it("passes overflow events through without evicting pending IDs", () => {
const filter = createDuplicateEventFilter()
for (let index = 0; index < 1024; index++) {
expect(
filter({
id: `pending-${index}`,
type: "message.part.updated",
properties: { sessionID: "s6", part, delta: "x" },
}),
).toBe(false)
}
expect(
filter({
id: "overflow",
type: "message.part.updated",
properties: { sessionID: "s6", part, delta: "x" },
}),
).toBe(false)
expect(
filter(
sync({
type: "sync",
name: "message.part.updated.1",
id: "overflow",
seq: 8,
aggregateID: "s6",
data: { sessionID: "s6", part, time: 0 },
}),
),
).toBe(false)
expect(
filter(
sync({
type: "sync",
name: "message.part.updated.1",
id: "pending-0",
seq: 9,
aggregateID: "s6",
data: { sessionID: "s6", part, time: 0 },
}),
),
).toBe(true)
expect(
filter({
id: "after-free",
type: "message.part.updated",
properties: { sessionID: "s6", part, delta: "x" },
}),
).toBe(false)
expect(
filter(
sync({
type: "sync",
name: "message.part.updated.1",
id: "after-free",
seq: 10,
aggregateID: "s6",
data: { sessionID: "s6", part, time: 0 },
}),
),
).toBe(true)
})
it("does not carry duplicate IDs between connections", () => {
const first = createDuplicateEventFilter()
const second = createDuplicateEventFilter()
const live = {
id: "connection-event",
type: "message.part.updated",
properties: { sessionID: "s6", part, delta: "x" },
} satisfies Payload
expect(first(live)).toBe(false)
expect(
second(
sync({
type: "sync",
name: "message.part.updated.1",
id: "connection-event",
seq: 11,
aggregateID: "s6",
data: { sessionID: "s6", part, time: 0 },
}),
),
).toBe(false)
})
})