feat(coding-agent): added snapcompact savings journaling for imaged tool results
- Added a `snapcompact-savings.jsonl` append-only journal for per-tool savings records. - Extended `SnapcompactInlineTransformer` to compute `savedTokens` and emit savings to an optional sink. - Integrated `createSnapcompactSavingsRecorder` into `createAgentSession` for session-aware tool-result metrics. - Skipped journaling entries without a session and deduped duplicate `toolCallId`s per recorder lifecycle. - Added tests for savings-sink emissions and savings-journal read/write behavior.
This commit is contained in:
@@ -115,6 +115,40 @@ describe("SnapcompactInlineTransformer", () => {
|
||||
expect(result.systemPrompt).toBe(context.systemPrompt);
|
||||
});
|
||||
|
||||
it("reports per-tool-result savings to the sink for each imaged result only", () => {
|
||||
const received: Array<{ toolCallId: string; savedTokens: number }>[] = [];
|
||||
let model = "";
|
||||
const transformer = new SnapcompactInlineTransformer(
|
||||
{ renderSystemPrompt: "none", renderToolResults: true },
|
||||
(savings, m) => {
|
||||
received.push(savings.map(s => ({ ...s })));
|
||||
model = m.id;
|
||||
},
|
||||
);
|
||||
transformer.transform(makeContext(), makeModel());
|
||||
|
||||
// Only the large historical result (call_1) is imaged; call_2 is small,
|
||||
// call_3 is the most-recent (kept crisp).
|
||||
expect(received).toHaveLength(1);
|
||||
expect(received[0]).toHaveLength(1);
|
||||
expect(received[0][0].toolCallId).toBe("call_1");
|
||||
expect(received[0][0].savedTokens).toBeGreaterThan(0);
|
||||
expect(model).toBe("test-model");
|
||||
});
|
||||
|
||||
it("never calls the savings sink when nothing is imaged", () => {
|
||||
let calls = 0;
|
||||
const transformer = new SnapcompactInlineTransformer(
|
||||
{ renderSystemPrompt: "none", renderToolResults: true },
|
||||
() => {
|
||||
calls++;
|
||||
},
|
||||
);
|
||||
// Text-only model → vision gate short-circuits before any swap.
|
||||
transformer.transform(makeContext(), makeModel({ input: ["text"] }));
|
||||
expect(calls).toBe(0);
|
||||
});
|
||||
|
||||
it("never mutates the input context (persisted history shares these references)", () => {
|
||||
const transformer = new SnapcompactInlineTransformer({ renderSystemPrompt: "all", renderToolResults: true });
|
||||
const context = makeContext();
|
||||
|
||||
Reference in New Issue
Block a user