import { describe, expect, mock, test } from "bun:test";
mock.module("../persistence/conversation-crud.js", () => ({
setConversationProcessingStartedAt: () => {},
isConversationProcessing: () => false,
getMessages: () => [],
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
}));
mock.module("../persistence/attachments-store.js", () => ({
getAttachmentMetadataForMessage: () => [],
getAttachmentContent: () => null,
}));
import { runAssistantDrivenCompaction } from "../context/compactor.js";
import type { Message, Provider } from "../providers/types.js";
const TAIL_TIMESTAMP =
"2026-05-21 (Thursday) 10:00:00 -05:00 (America/Chicago)";
const compactionResponse = `
Earlier turns summarized here.
- Nothing critical pending.
`;
function makeProvider(): Provider {
return {
name: "mock-provider",
sendMessage: async () => ({
content: [{ type: "text", text: compactionResponse }],
model: "mock-model",
usage: { inputTokens: 100, outputTokens: 50 },
stopReason: "end_turn",
}),
};
}
const userText = (text: string): Message => ({
role: "user",
content: [{ type: "text", text }],
});
const userTextWithTurnContext = (text: string, timestamp: string): Message => ({
role: "user",
content: [
{
type: "text",
text: `\ncurrent_time: ${timestamp}\n\n${text}`,
},
],
});
const assistantText = (text: string): Message => ({
role: "assistant",
content: [{ type: "text", text }],
});
describe("runAssistantDrivenCompaction — preservedTailMessages count", () => {
test("reflects the pre-strip tail size so the reported cut point matches the user-visible split", async () => {
const messages: Message[] = [
userText("old user turn 1"),
assistantText("old assistant reply 1"),
userText("old user turn 2"),
userTextWithTurnContext("tail anchor message", TAIL_TIMESTAMP),
userText("\nstale reminder\n"),
userText("\nstale pkb\n"),
assistantText("most recent assistant reply"),
];
const result = await runAssistantDrivenCompaction({
conversationId: "conv-test",
messages,
provider: makeProvider(),
systemPrompt: "system",
compaction: { enabled: true, autoThreshold: 0.7 },
maxInputTokens: 1000,
previousEstimatedInputTokens: 900,
});
expect(result.compacted).toBe(true);
expect(result.preservedTailMessages).toBe(4);
});
});