Skip to content

Commit ae0741a

Browse files
committed
feat(compaction): add staged helpers
1 parent 4ee70be commit ae0741a

2 files changed

Lines changed: 411 additions & 0 deletions

File tree

src/agents/compaction.test.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import type { AgentMessage } from "@mariozechner/pi-agent-core";
2+
import { describe, expect, it } from "vitest";
3+
4+
import {
5+
estimateMessagesTokens,
6+
pruneHistoryForContextShare,
7+
splitMessagesByTokenShare,
8+
} from "./compaction.js";
9+
10+
function makeMessage(id: number, size: number): AgentMessage {
11+
return {
12+
role: "user",
13+
content: "x".repeat(size),
14+
timestamp: id,
15+
};
16+
}
17+
18+
describe("splitMessagesByTokenShare", () => {
19+
it("splits messages into two non-empty parts", () => {
20+
const messages: AgentMessage[] = [
21+
makeMessage(1, 4000),
22+
makeMessage(2, 4000),
23+
makeMessage(3, 4000),
24+
makeMessage(4, 4000),
25+
];
26+
27+
const parts = splitMessagesByTokenShare(messages, 2);
28+
expect(parts.length).toBeGreaterThanOrEqual(2);
29+
expect(parts[0]?.length).toBeGreaterThan(0);
30+
expect(parts[1]?.length).toBeGreaterThan(0);
31+
expect(parts.flat().length).toBe(messages.length);
32+
});
33+
});
34+
35+
describe("pruneHistoryForContextShare", () => {
36+
it("drops older chunks until the history budget is met", () => {
37+
const messages: AgentMessage[] = [
38+
makeMessage(1, 4000),
39+
makeMessage(2, 4000),
40+
makeMessage(3, 4000),
41+
makeMessage(4, 4000),
42+
];
43+
const maxContextTokens = 2000; // budget is 1000 tokens (50%)
44+
const pruned = pruneHistoryForContextShare({
45+
messages,
46+
maxContextTokens,
47+
maxHistoryShare: 0.5,
48+
parts: 2,
49+
});
50+
51+
expect(pruned.droppedChunks).toBeGreaterThan(0);
52+
expect(pruned.keptTokens).toBeLessThanOrEqual(Math.floor(maxContextTokens * 0.5));
53+
expect(pruned.messages.length).toBeGreaterThan(0);
54+
});
55+
56+
it("keeps history when already within budget", () => {
57+
const messages: AgentMessage[] = [makeMessage(1, 1000)];
58+
const maxContextTokens = 2000;
59+
const pruned = pruneHistoryForContextShare({
60+
messages,
61+
maxContextTokens,
62+
maxHistoryShare: 0.5,
63+
parts: 2,
64+
});
65+
66+
expect(pruned.droppedChunks).toBe(0);
67+
expect(pruned.messages.length).toBe(messages.length);
68+
expect(pruned.keptTokens).toBe(estimateMessagesTokens(messages));
69+
});
70+
});

0 commit comments

Comments
 (0)