fix: align compaction cuts and native usage accounting
This commit is contained in:
@@ -32,7 +32,7 @@ const {
|
||||
} = await import("../src/server/compaction.ts");
|
||||
import type { CompactionDeps } from "../src/server/compaction.ts";
|
||||
const { subscribe } = await import("../src/core/events.ts");
|
||||
const { activeCompactionOf, newUserMessage, COMPACTED_HISTORY_HEADER } = await import("../src/core/index.ts");
|
||||
const { activeCompactionOf, newUserMessage, measuredContextTokens, COMPACTED_HISTORY_HEADER } = await import("../src/core/index.ts");
|
||||
import type { LhMessage } from "../src/core/index.ts";
|
||||
|
||||
after(() => {
|
||||
@@ -204,6 +204,37 @@ describe("the compaction service", () => {
|
||||
kickCompaction(() => null, chatId);
|
||||
});
|
||||
|
||||
it("a usage-heavy zero cut does not spend or append a marker", async () => {
|
||||
const chat = chatStore.createChat("no-progress fixture");
|
||||
const assistant = { id: "measured", role: "assistant", content: [{ type: "text", text: "ok" }], stopReason: "stop", usage: { input: 120_000, output: 1, cacheRead: 0, cacheWrite: 0, totalTokens: 120_001 }, timestamp: 1 } as LhMessage;
|
||||
chatStore.saveMessages(chat.id, [newUserMessage("tiny visible history"), assistant]);
|
||||
const before = summarizeCalls;
|
||||
await ensureCompacted(depsOf(chat.id, 40_000), chat.id);
|
||||
assert.equal(summarizeCalls, before);
|
||||
assert.equal(activeCompactionOf(chatStore.getChat(chat.id)!.messages), null);
|
||||
assert.equal(measuredContextTokens(chatStore.getChat(chat.id)!.messages), 120_001);
|
||||
});
|
||||
|
||||
it("starting/failing compaction preserves the meter; committing its marker clears it, regardless of summary usage", async () => {
|
||||
const id = overThresholdChat("meter validity fixture");
|
||||
const assistant = { id: "measured", role: "assistant", content: [{ type: "text", text: "ok" }], stopReason: "stop", usage: { input: 120_000, output: 1, cacheRead: 0, cacheWrite: 0, totalTokens: 120_001 }, timestamp: 1 } as LhMessage;
|
||||
chatStore.saveMessages(id, [...chatStore.getChat(id)!.messages, assistant]);
|
||||
let release!: () => void;
|
||||
const gate = new Promise<void>((done) => { release = done; });
|
||||
const deps = depsOf(id, 40_000);
|
||||
const running = ensureCompacted({ ...deps, summarize: async () => {
|
||||
await gate;
|
||||
throw new Error("fixture failure");
|
||||
} }, id);
|
||||
assert.equal(measuredContextTokens(chatStore.getChat(id)!.messages), 120_001);
|
||||
release(); await running;
|
||||
assert.equal(measuredContextTokens(chatStore.getChat(id)!.messages), 120_001);
|
||||
await ensureCompacted(deps, id);
|
||||
const record = chatStore.getChat(id)!;
|
||||
assert.ok(record.turns!.at(-1)!.steps[0]!.inputTokens! > 0);
|
||||
assert.equal(measuredContextTokens(record.messages), null);
|
||||
});
|
||||
|
||||
it("a summarizer failure leaves the record untouched and the gate re-arms", async () => {
|
||||
const chatId = overThresholdChat("compact: fail");
|
||||
const before = summarizeCalls;
|
||||
|
||||
Reference in New Issue
Block a user