@@ -98,6 +98,7 @@ describe.skipIf(!API_KEY)("Compaction extensions", () => {
|
||||
|
||||
const sessionManager = SessionManager.create(tempDir);
|
||||
const settingsManager = SettingsManager.create(tempDir, tempDir);
|
||||
settingsManager.applyOverrides({ compaction: { keepRecentTokens: 1 } });
|
||||
const authStorage = AuthStorage.create(join(tempDir, "auth.json"));
|
||||
const modelRegistry = ModelRegistry.create(authStorage);
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
calculateContextTokens,
|
||||
compact,
|
||||
DEFAULT_COMPACTION_SETTINGS,
|
||||
estimateContextTokens,
|
||||
findCutPoint,
|
||||
getLastAssistantUsage,
|
||||
prepareCompaction,
|
||||
@@ -396,7 +395,7 @@ describe("buildSessionContext", () => {
|
||||
});
|
||||
|
||||
describe("prepareCompaction with previous compaction", () => {
|
||||
it("should preserve kept messages across repeated compactions when they still fit", () => {
|
||||
it("should skip repeated compactions when kept messages still fit", () => {
|
||||
const u1 = createMessageEntry(createUserMessage("user msg 1 (summarized by compaction1)"));
|
||||
const a1 = createMessageEntry(createAssistantMessage("assistant msg 1"));
|
||||
const u2 = createMessageEntry(createUserMessage("user msg 2 - kept by compaction1"));
|
||||
@@ -408,29 +407,9 @@ describe("prepareCompaction with previous compaction", () => {
|
||||
const a4 = createMessageEntry(createAssistantMessage("assistant msg 4", createMockUsage(8000, 2000)));
|
||||
|
||||
const pathEntries = [u1, a1, u2, a2, u3, a3, compaction1, u4, a4];
|
||||
const contextBefore = buildSessionContext(pathEntries);
|
||||
const preparation = prepareCompaction(pathEntries, DEFAULT_COMPACTION_SETTINGS);
|
||||
|
||||
expect(preparation).toBeDefined();
|
||||
expect(preparation!.firstKeptEntryId).toBe(u2.id);
|
||||
expect(preparation!.previousSummary).toBe("First summary");
|
||||
expect(extractText(preparation!.messagesToSummarize)).not.toContain("First summary");
|
||||
expect(preparation!.tokensBefore).toBe(estimateContextTokens(contextBefore.messages).tokens);
|
||||
|
||||
const compaction2: CompactionEntry = {
|
||||
type: "compaction",
|
||||
id: "compaction2-id",
|
||||
parentId: a4.id,
|
||||
timestamp: new Date().toISOString(),
|
||||
summary: "Second summary",
|
||||
firstKeptEntryId: preparation!.firstKeptEntryId,
|
||||
tokensBefore: preparation!.tokensBefore,
|
||||
};
|
||||
const contextAfter = buildSessionContext([...pathEntries, compaction2]);
|
||||
const contextAfterText = extractText(contextAfter.messages);
|
||||
|
||||
expect(contextAfterText).toContain("user msg 2 - kept by compaction1");
|
||||
expect(contextAfterText).toContain("user msg 3 - kept by compaction1");
|
||||
expect(preparation).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should re-summarize previously kept messages when the recent window moves past them", () => {
|
||||
|
||||
@@ -67,19 +67,20 @@ function useSummaryStreamFn(harness: Harness, summary: string): () => number {
|
||||
}
|
||||
|
||||
function seedCompactableSession(harness: Harness): void {
|
||||
harness.settingsManager.applyOverrides({ compaction: { keepRecentTokens: 1 } });
|
||||
const now = Date.now();
|
||||
harness.sessionManager.appendMessage({
|
||||
role: "user",
|
||||
content: [{ type: "text", text: "message to compact" }],
|
||||
timestamp: now - 1000,
|
||||
});
|
||||
harness.sessionManager.appendMessage(
|
||||
createAssistant(harness, {
|
||||
stopReason: "stop",
|
||||
totalTokens: 100,
|
||||
timestamp: now - 500,
|
||||
}),
|
||||
);
|
||||
const assistant = createAssistant(harness, {
|
||||
stopReason: "stop",
|
||||
totalTokens: 100,
|
||||
timestamp: now - 500,
|
||||
});
|
||||
assistant.content = [{ type: "text", text: "assistant response to compact" }];
|
||||
harness.sessionManager.appendMessage(assistant);
|
||||
harness.session.agent.state.messages = harness.sessionManager.buildSessionContext().messages;
|
||||
}
|
||||
|
||||
@@ -96,6 +97,7 @@ describe("AgentSession compaction characterization", () => {
|
||||
|
||||
it("manually compacts using an extension-provided summary", async () => {
|
||||
const harness = await createHarness({
|
||||
settings: { compaction: { keepRecentTokens: 1 } },
|
||||
extensionFactories: [
|
||||
(pi) => {
|
||||
pi.on("session_before_compact", async (event) => ({
|
||||
@@ -145,7 +147,7 @@ describe("AgentSession compaction characterization", () => {
|
||||
|
||||
const result = await harness.session.compact();
|
||||
|
||||
expect(result.summary).toBe("summary from custom stream");
|
||||
expect(result.summary).toContain("summary from custom stream");
|
||||
expect(getStreamCallCount()).toBe(1);
|
||||
});
|
||||
|
||||
@@ -165,6 +167,7 @@ describe("AgentSession compaction characterization", () => {
|
||||
|
||||
it("cancels in-progress manual compaction when abortCompaction is called", async () => {
|
||||
const harness = await createHarness({
|
||||
settings: { compaction: { keepRecentTokens: 1 } },
|
||||
extensionFactories: [
|
||||
(pi) => {
|
||||
pi.on("session_before_compact", async (event) => {
|
||||
|
||||
Reference in New Issue
Block a user