fix(sync): skip duplicate status events (#1152)
* fix(sync): skip duplicate status events * test(sync): cover duplicate idle statuses --------- Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
Isaac Sanchez
Bohdan Triapitsyn
parent
c1c21fe340
commit
14c0bfe0bc
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import type { Event, Part, PermissionRequest, QuestionRequest } from "@opencode-ai/sdk/v2/client"
|
||||
import type { Event, Part, PermissionRequest, QuestionRequest, SessionStatus } from "@opencode-ai/sdk/v2/client"
|
||||
import { applyDirectoryEvent } from "../event-reducer"
|
||||
import { INITIAL_STATE, type State } from "../types"
|
||||
|
||||
@@ -8,6 +8,7 @@ function state(overrides: Partial<State> = {}): State {
|
||||
...INITIAL_STATE,
|
||||
message: {},
|
||||
part: {},
|
||||
session_status: {},
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
@@ -87,6 +88,68 @@ describe("applyDirectoryEvent", () => {
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
|
||||
test("skips duplicate session status events", () => {
|
||||
const draft = state()
|
||||
const busyStatus = { type: "busy" } as SessionStatus
|
||||
const event = {
|
||||
type: "session.status",
|
||||
properties: { sessionID: "ses_1", status: busyStatus },
|
||||
} as Event
|
||||
|
||||
expect(applyDirectoryEvent(draft, event)).toBe(true)
|
||||
const statusRef = draft.session_status.ses_1
|
||||
|
||||
expect(applyDirectoryEvent(draft, event)).toBe(false)
|
||||
expect(draft.session_status.ses_1).toBe(statusRef)
|
||||
})
|
||||
|
||||
test("skips duplicate session idle events", () => {
|
||||
const draft = state()
|
||||
const event = {
|
||||
type: "session.idle",
|
||||
properties: { sessionID: "ses_1" },
|
||||
} as Event
|
||||
|
||||
expect(applyDirectoryEvent(draft, event)).toBe(true)
|
||||
const statusRef = draft.session_status.ses_1
|
||||
|
||||
expect(applyDirectoryEvent(draft, event)).toBe(false)
|
||||
expect(draft.session_status.ses_1).toBe(statusRef)
|
||||
})
|
||||
|
||||
test("skips duplicate session error idle-state events", () => {
|
||||
const draft = state()
|
||||
const event = {
|
||||
type: "session.error",
|
||||
properties: { sessionID: "ses_1" },
|
||||
} as Event
|
||||
|
||||
expect(applyDirectoryEvent(draft, event)).toBe(true)
|
||||
const statusRef = draft.session_status.ses_1
|
||||
|
||||
expect(applyDirectoryEvent(draft, event)).toBe(false)
|
||||
expect(draft.session_status.ses_1).toBe(statusRef)
|
||||
})
|
||||
|
||||
test("detects retry status metadata changes", () => {
|
||||
const draft = state({
|
||||
session_status: {
|
||||
ses_1: { type: "retry", attempt: 1, message: "rate limited", next: 10 } as SessionStatus,
|
||||
},
|
||||
})
|
||||
|
||||
const event = {
|
||||
type: "session.status",
|
||||
properties: {
|
||||
sessionID: "ses_1",
|
||||
status: { type: "retry", attempt: 2, message: "rate limited", next: 20 } as SessionStatus,
|
||||
},
|
||||
} as Event
|
||||
|
||||
expect(applyDirectoryEvent(draft, event)).toBe(true)
|
||||
expect((draft.session_status.ses_1 as Extract<SessionStatus, { type: "retry" }>).attempt).toBe(2)
|
||||
})
|
||||
|
||||
test("updates permission request arrays immutably", () => {
|
||||
const initialPermissions = [
|
||||
{ id: "perm_1", sessionID: "ses_1" } as PermissionRequest,
|
||||
|
||||
@@ -90,6 +90,18 @@ function shouldPreserveExistingPart(previous: Part, next: Part): boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
function areSessionStatusesEqual(left: SessionStatus | undefined, right: SessionStatus): boolean {
|
||||
if (left === right) return true
|
||||
if (!left || left.type !== right.type) return false
|
||||
if (left.type === "retry") {
|
||||
return right.type === "retry"
|
||||
&& left.attempt === right.attempt
|
||||
&& left.message === right.message
|
||||
&& left.next === right.next
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Global events
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -219,19 +231,30 @@ export function applyDirectoryEvent(
|
||||
|
||||
case "session.status": {
|
||||
const props = event.properties as { sessionID: string; status: SessionStatus }
|
||||
if (areSessionStatusesEqual(draft.session_status[props.sessionID], props.status)) {
|
||||
return false
|
||||
}
|
||||
draft.session_status[props.sessionID] = props.status
|
||||
return true
|
||||
}
|
||||
|
||||
case "session.idle": {
|
||||
const props = event.properties as { sessionID: string }
|
||||
draft.session_status[props.sessionID] = { type: "idle" }
|
||||
const status = { type: "idle" } as const
|
||||
if (areSessionStatusesEqual(draft.session_status[props.sessionID], status)) {
|
||||
return false
|
||||
}
|
||||
draft.session_status[props.sessionID] = status
|
||||
return true
|
||||
}
|
||||
|
||||
case "session.error": {
|
||||
const props = event.properties as { sessionID: string }
|
||||
draft.session_status[props.sessionID] = { type: "idle" }
|
||||
const status = { type: "idle" } as const
|
||||
if (areSessionStatusesEqual(draft.session_status[props.sessionID], status)) {
|
||||
return false
|
||||
}
|
||||
draft.session_status[props.sessionID] = status
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user