1import { describe, expect, it } from "vite-plus/test";
2import * as DateTime from "effect/DateTime";
3import {
4 deriveLatestContextWindowSnapshot,
5 formatContextWindowTokens,
6 latestProviderTurnTokenUsage,
7} from "./contextWindow";
8
9describe("V2 context window presentation", () => {
10 it("uses retained compaction token data when available", () => {
11 const snapshot = deriveLatestContextWindowSnapshot([
12 {
13 item: {
14 id: "compaction-1" as never,
15 threadId: "thread-1" as never,
16 runId: null,
17 nodeId: null,
18 providerThreadId: null,
19 providerTurnId: null,
20 nativeItemRef: null,
21 parentItemId: null,
22 ordinal: 1,
23 status: "completed",
24 title: null,
25 startedAt: null,
26 completedAt: null,
27 updatedAt: DateTime.makeUnsafe("2026-06-20T00:00:00.000Z"),
28 type: "compaction",
29 driver: null,
30 beforeTokenCount: 10_000,
31 afterTokenCount: 2_000,
32 },
33 },
34 ]);
35 expect(snapshot?.usedTokens).toBe(2_000);
36 expect(snapshot?.totalProcessedTokens).toBe(10_000);
37 });
38
39 it("prefers current provider usage and preserves ACP cost", () => {
40 const snapshot = deriveLatestContextWindowSnapshot([], undefined, {
41 contextUsage: {
42 usedTokens: 2_500,
43 maxTokens: 10_000,
44 cost: { amount: 0.42, currency: "USD" },
45 },
46 updatedAt: DateTime.makeUnsafe("2026-08-23T00:00:00.000Z"),
47 });
48
49 expect(snapshot).toMatchObject({
50 usedTokens: 2_500,
51 maxTokens: 10_000,
52 remainingTokens: 7_500,
53 usedPercentage: 25,
54 cost: { amount: 0.42, currency: "USD" },
55 });
56 });
57
58 it("formats compact token values", () => {
59 expect(formatContextWindowTokens(1_500)).toBe("1.5k");
60 });
61
62 it.each([
63 [999_499, "999k"],
64 [999_500, "1m"],
65 [999_999, "1m"],
66 [1_000_000, "1m"],
67 [1_100_000, "1.1m"],
68 ])("formats %d tokens as %s at the million boundary", (tokens, expected) => {
69 expect(formatContextWindowTokens(tokens)).toBe(expected);
70 });
71});
72
73describe("live provider-turn usage (#8144)", () => {
74 it("prefers the provider's live report over compaction items", () => {
75 const snapshot = deriveLatestContextWindowSnapshot([], {
76 usedTokens: 42_000,
77 maxTokens: 200_000,
78 inputTokens: 40_000,
79 outputTokens: 2_000,
80 updatedAt: "2026-08-27T00:00:00.000Z",
81 });
82 expect(snapshot).not.toBeNull();
83 expect(snapshot?.usedTokens).toBe(42_000);
84 expect(snapshot?.maxTokens).toBe(200_000);
85 expect(snapshot?.remainingTokens).toBe(158_000);
86 expect(snapshot?.usedPercentage).toBe(21);
87 });
88
89 it("handles a report without a known context window", () => {
90 const snapshot = deriveLatestContextWindowSnapshot([], {
91 usedTokens: 42_000,
92 updatedAt: "2026-08-27T00:00:00.000Z",
93 });
94 expect(snapshot?.maxTokens).toBeNull();
95 expect(snapshot?.usedPercentage).toBeNull();
96 });
97});
98
99describe("latestProviderTurnTokenUsage", () => {
100 it("picks the newest report, not the last turn in snapshot order", () => {
101 const usage = (usedTokens: number, updatedAt: string) => ({
102 tokenUsage: { usedTokens, updatedAt },
103 });
104 // Snapshots sort by provider thread id, so an older thread can come last.
105 const latest = latestProviderTurnTokenUsage([
106 usage(300_000, "2026-06-20T12:00:00.000Z"),
107 {},
108 usage(90_000, "2026-06-20T09:00:00.000Z"),
109 ]);
110 expect(latest?.usedTokens).toBe(300_000);
111 });
112});