fix(preemptive-compaction): mock session history in degradation test

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-03-24 20:36:22 +09:00
parent cea8769a7f
commit d2e566ba9d
@@ -1,3 +1,5 @@
/// <reference types="bun-types" />
import { beforeEach, describe, expect, it, mock } from "bun:test" import { beforeEach, describe, expect, it, mock } from "bun:test"
const logMock = mock(() => {}) const logMock = mock(() => {})
@@ -8,11 +10,19 @@ mock.module("../shared/logger", () => ({
const { createPreemptiveCompactionHook } = await import("./preemptive-compaction") const { createPreemptiveCompactionHook } = await import("./preemptive-compaction")
function createMockCtx() { type AssistantHistoryMessage = {
info: {
id: string
role: "assistant"
}
parts: Array<{ type: string; text?: string }>
}
function createMockCtx(sessionHistory: AssistantHistoryMessage[]) {
return { return {
client: { client: {
session: { session: {
messages: mock(() => Promise.resolve({ data: [] })), messages: mock(() => Promise.resolve({ data: sessionHistory })),
summarize: mock(() => Promise.resolve({})), summarize: mock(() => Promise.resolve({})),
}, },
tui: { tui: {
@@ -23,6 +33,22 @@ function createMockCtx() {
} }
} }
function appendAssistantHistory(
sessionHistory: AssistantHistoryMessage[],
input: {
id: string
parts: AssistantHistoryMessage["parts"]
},
): void {
sessionHistory.push({
info: {
id: input.id,
role: "assistant",
},
parts: input.parts,
})
}
function buildAssistantUpdate(input: { function buildAssistantUpdate(input: {
sessionID: string sessionID: string
id: string id: string
@@ -69,7 +95,9 @@ describe("preemptive-compaction post-compaction degradation monitor", () => {
}) })
it("triggers recovery summarize after three consecutive no-text tail messages", async () => { it("triggers recovery summarize after three consecutive no-text tail messages", async () => {
const ctx = createMockCtx() // given
const sessionHistory: AssistantHistoryMessage[] = []
const ctx = createMockCtx(sessionHistory)
const hook = createPreemptiveCompactionHook(ctx as never, {} as never) const hook = createPreemptiveCompactionHook(ctx as never, {} as never)
const sessionID = "ses_tail_recovery" const sessionID = "ses_tail_recovery"
@@ -82,10 +110,17 @@ describe("preemptive-compaction post-compaction degradation monitor", () => {
const stepOnlyParts = [{ type: "step-start" }, { type: "step-finish" }] const stepOnlyParts = [{ type: "step-start" }, { type: "step-finish" }]
// when
appendAssistantHistory(sessionHistory, { id: "msg_1", parts: stepOnlyParts })
await hook.event(buildAssistantUpdate({ sessionID, id: "msg_1", parts: stepOnlyParts })) await hook.event(buildAssistantUpdate({ sessionID, id: "msg_1", parts: stepOnlyParts }))
appendAssistantHistory(sessionHistory, { id: "msg_2", parts: stepOnlyParts })
await hook.event(buildAssistantUpdate({ sessionID, id: "msg_2", parts: stepOnlyParts })) await hook.event(buildAssistantUpdate({ sessionID, id: "msg_2", parts: stepOnlyParts }))
appendAssistantHistory(sessionHistory, { id: "msg_3", parts: stepOnlyParts })
await hook.event(buildAssistantUpdate({ sessionID, id: "msg_3", parts: stepOnlyParts })) await hook.event(buildAssistantUpdate({ sessionID, id: "msg_3", parts: stepOnlyParts }))
// then
expect(ctx.client.session.summarize).toHaveBeenCalledTimes(1) expect(ctx.client.session.summarize).toHaveBeenCalledTimes(1)
expect(ctx.client.tui.showToast).toHaveBeenCalledTimes(1) expect(ctx.client.tui.showToast).toHaveBeenCalledTimes(1)
expect(logMock).toHaveBeenCalledWith( expect(logMock).toHaveBeenCalledWith(
@@ -98,7 +133,9 @@ describe("preemptive-compaction post-compaction degradation monitor", () => {
}) })
it("resets no-text streak when assistant emits text content", async () => { it("resets no-text streak when assistant emits text content", async () => {
const ctx = createMockCtx() // given
const sessionHistory: AssistantHistoryMessage[] = []
const ctx = createMockCtx(sessionHistory)
const hook = createPreemptiveCompactionHook(ctx as never, {} as never) const hook = createPreemptiveCompactionHook(ctx as never, {} as never)
const sessionID = "ses_tail_reset" const sessionID = "ses_tail_reset"
@@ -109,30 +146,48 @@ describe("preemptive-compaction post-compaction degradation monitor", () => {
}, },
}) })
// when
appendAssistantHistory(sessionHistory, {
id: "msg_1",
parts: [{ type: "step-start" }, { type: "step-finish" }],
})
await hook.event(buildAssistantUpdate({ await hook.event(buildAssistantUpdate({
sessionID, sessionID,
id: "msg_1", id: "msg_1",
parts: [{ type: "step-start" }, { type: "step-finish" }], parts: [{ type: "step-start" }, { type: "step-finish" }],
})) }))
appendAssistantHistory(sessionHistory, {
id: "msg_2",
parts: [{ type: "text", text: "Recovered response" }],
})
await hook.event(buildAssistantUpdate({ await hook.event(buildAssistantUpdate({
sessionID, sessionID,
id: "msg_2", id: "msg_2",
parts: [{ type: "text", text: "Recovered response" }], parts: [{ type: "text", text: "Recovered response" }],
})) }))
appendAssistantHistory(sessionHistory, {
id: "msg_3",
parts: [{ type: "step-start" }, { type: "step-finish" }],
})
await hook.event(buildAssistantUpdate({ await hook.event(buildAssistantUpdate({
sessionID, sessionID,
id: "msg_3", id: "msg_3",
parts: [{ type: "step-start" }, { type: "step-finish" }], parts: [{ type: "step-start" }, { type: "step-finish" }],
})) }))
appendAssistantHistory(sessionHistory, {
id: "msg_4",
parts: [{ type: "step-start" }, { type: "step-finish" }],
})
await hook.event(buildAssistantUpdate({ await hook.event(buildAssistantUpdate({
sessionID, sessionID,
id: "msg_4", id: "msg_4",
parts: [{ type: "step-start" }, { type: "step-finish" }], parts: [{ type: "step-start" }, { type: "step-finish" }],
})) }))
// then
expect(ctx.client.session.summarize).not.toHaveBeenCalled() expect(ctx.client.session.summarize).not.toHaveBeenCalled()
}) })
}) })