fix(tui): filter duplicate event work

This commit is contained in:
Kit Langton 2026-07-10 12:13:41 -04:00
commit 1d11bf84c9
4 changed files with 71 additions and 15 deletions

View file

@ -104,6 +104,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
const [defaultLocation, setDefaultLocation] = createSignal<LocationRef>({
directory: process.cwd(),
})
let defaultLocationReady = false
const messageIndex = new Map<string, Map<string, number>>()
let bootstrapping: Promise<void> | undefined
let connected = false
@ -233,6 +234,16 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
}
function handleEvent(event: OpenCodeEvent) {
if (
defaultLocationReady &&
event.type.startsWith("session.") &&
"sessionID" in event.data &&
typeof event.data.sessionID === "string" &&
!store.session.info[event.data.sessionID] &&
event.location &&
locationKey(event.location) !== locationKey(defaultLocation())
)
return
switch (event.type) {
case "session.created":
void result.session.refresh(event.data.sessionID)
@ -912,7 +923,10 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
const location = await sdk.api.location.get({ location: locationQuery(ref ?? defaultLocation()) })
const key = locationKey(location)
if (!store.location[key]) setStore("location", key, {})
if (!ref) setDefaultLocation({ directory: location.directory, workspaceID: location.workspaceID })
if (!ref) {
setDefaultLocation({ directory: location.directory, workspaceID: location.workspaceID })
defaultLocationReady = true
}
},
agent: {
list(location?: LocationRef) {

View file

@ -92,12 +92,6 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
const event = await iterator.next()
if (abort.signal.aborted || controller.signal.aborted) return
if (event.done) return new Error("Event stream disconnected")
if ("durable" in event.value)
log.info("event", {
type: event.value.type,
aggregateID: event.value.durable.aggregateID,
seq: event.value.durable.seq,
})
events.emit(event.value.type, event.value)
}
})()

View file

@ -122,6 +122,59 @@ test("refreshes resources into reactive getters", async () => {
}
})
test("does not materialize messages for unknown sessions in other locations", async () => {
const events = createEventStream()
const sessionID = "ses_unloaded"
const calls = createFetch((url) => {
if (url.pathname === `/api/session/${sessionID}/message`) return json({ data: [], cursor: {} })
}, events)
let data!: ReturnType<typeof useData>
function Probe() {
data = useData()
return <box />
}
const app = await testRender(() => (
<TestTuiContexts>
<SDKProvider client={createClient(calls.fetch)} api={createApi(calls.fetch)}>
<ProjectProvider>
<DataProvider>
<Probe />
</DataProvider>
</ProjectProvider>
</SDKProvider>
</TestTuiContexts>
))
const started = (id: string, seq: number): OpenCodeEvent => ({
id: `evt_${id}`,
created: seq,
type: "session.step.started",
durable: durable(sessionID, seq),
data: {
sessionID,
assistantMessageID: id,
agent: "build",
model: { providerID: "provider", id: "model" },
},
})
try {
await wait(() => data.location.default().directory === directory)
events.emit({ ...started("msg_ignored", 1), location: { directory: "/tmp/other" } })
await Bun.sleep(20)
expect(data.session.message.ids(sessionID)).toEqual([])
await data.session.message.refresh(sessionID)
emitEvent(events, started("msg_loaded", 2))
await wait(() => data.session.message.ids(sessionID).length === 1)
expect(data.session.message.ids(sessionID)).toEqual(["msg_loaded"])
} finally {
app.renderer.destroy()
}
})
test("applies absolute usage events to session info", async () => {
const events = createEventStream()
const sessionID = "ses_usage_refresh"

View file

@ -112,7 +112,7 @@ function Probe(props: {
}
describe("useEvent", () => {
test("logs only durable events", async () => {
test("does not log individual events", async () => {
const logs: Array<{ message: string; tags: Readonly<Record<string, unknown>> }> = []
const { app, emit, seen } = await mount(undefined, (_level, message, tags) => {
if (message === "event") logs.push({ message, tags })
@ -131,14 +131,9 @@ describe("useEvent", () => {
try {
emit(vcs("main"))
emit(durable)
await wait(() => seen.length === 2 && logs.length === 1)
await wait(() => seen.length === 2)
expect(logs).toEqual([
{
message: "event",
tags: { component: "sdk", type: "session.renamed", aggregateID: "ses_test", seq: 1 },
},
])
expect(logs).toEqual([])
} finally {
app.renderer.destroy()
}