1package core
2
3import (
4 "testing"
5 "time"
6
7 "github.com/bnema/zut/packages/provider"
8)
9
10func TestSessionUsageDetailResetsContextAfterCompaction(t *testing.T) {
11 t.Run("compaction is latest row", func(t *testing.T) {
12 sess := newUsageTestSession(t)
13 before := provider.Usage{
14 InputTokens: 180,
15 OutputTokens: 20,
16 CacheReadTokens: 10,
17 CostUSD: 1.25,
18 }
19 if err := sess.AppendUsage(before, before); err != nil {
20 t.Fatal(err)
21 }
22 if err := sess.AppendCompaction([]provider.Message{{
23 Role: provider.RoleUser,
24 Content: []provider.Content{provider.TextBlock{Text: "summary"}},
25 Time: time.Now().UTC(),
26 }}); err != nil {
27 t.Fatal(err)
28 }
29 if err := sess.Close(); err != nil {
30 t.Fatal(err)
31 }
32
33 cumulative, lastTurn, err := SessionUsageDetail(sess.Path)
34 if err != nil {
35 t.Fatal(err)
36 }
37 if cumulative.InputTokens != before.InputTokens || cumulative.CostUSD != before.CostUSD {
38 t.Fatalf("cumulative usage = %+v, want %+v", cumulative, before)
39 }
40 if lastTurn != (provider.Usage{}) {
41 t.Fatalf("last turn after compaction = %+v, want zero context usage", lastTurn)
42 }
43 })
44
45 t.Run("post-compaction usage wins", func(t *testing.T) {
46 sess := newUsageTestSession(t)
47 before := provider.Usage{InputTokens: 180, OutputTokens: 20, CacheReadTokens: 10}
48 if err := sess.AppendUsage(before, before); err != nil {
49 t.Fatal(err)
50 }
51 if err := sess.AppendCompaction([]provider.Message{{
52 Role: provider.RoleUser,
53 Content: []provider.Content{provider.TextBlock{Text: "summary"}},
54 Time: time.Now().UTC(),
55 }}); err != nil {
56 t.Fatal(err)
57 }
58 after := provider.Usage{InputTokens: 20, OutputTokens: 5, CacheReadTokens: 30}
59 cumulative := provider.Usage{InputTokens: 200, OutputTokens: 25, CacheReadTokens: 30}
60 if err := sess.AppendUsage(after, cumulative); err != nil {
61 t.Fatal(err)
62 }
63 if err := sess.Close(); err != nil {
64 t.Fatal(err)
65 }
66
67 _, lastTurn, err := SessionUsageDetail(sess.Path)
68 if err != nil {
69 t.Fatal(err)
70 }
71 if lastTurn.InputTokens != after.InputTokens || lastTurn.OutputTokens != after.OutputTokens {
72 t.Fatalf("post-compaction last turn = %+v, want input/output %+v", lastTurn, after)
73 }
74 })
75}
76
77func newUsageTestSession(t *testing.T) *Session {
78 t.Helper()
79 sess, err := NewSession(t.TempDir(), "/workspace", "anthropic", "test-model", "test")
80 if err != nil {
81 t.Fatal(err)
82 }
83 return sess
84}