返回 DeepSeek-Reasonix
compact_threshold_test.go
根目录 / internal / agent / compact_threshold_test.go
1 package agent
2
3 import "testing"
4
5 // An output budget larger than the window it shares must never change the
6 // sole compact_ratio trigger. Output is clipped only at send time.
7 func TestCompactTriggerIndependentOfOutputBudget(t *testing.T) {
8 a := &Agent{
9 svc: agentServices{prov: &sharedWindowTestProvider{budget: 131_072, shared: true}},
10 agentConfig: agentConfig{contextWindow: 128_000, compactRatio: defaultCompactRatio},
11 sess: sessionRuntime{output: outputBudgetState{outputBudget: 131_072}},
12 }
13 trigger := a.compactTrigger()
14 want := int(float64(128_000) * defaultCompactRatio)
15 if trigger != want {
16 t.Fatalf("trigger = %d, want %d (compact_ratio only)", trigger, want)
17 }
18 // Oversized output budget must not lower the trigger.
19 a.sess.output.outputBudget = 200_000
20 if got := a.compactTrigger(); got != want {
21 t.Fatalf("trigger after larger output budget = %d, want %d", got, want)
22 }
23 hard := a.hardInputCeiling()
24 if hard != 128_000-protocolReserveTokens {
25 t.Fatalf("hard ceiling = %d, want window-protocolReserve", hard)
26 }
27 }
28
29 func TestRecentTailBudgetIsFixedSixteenPercent(t *testing.T) {
30 cases := []struct {
31 window int
32 want int
33 }{
34 {10_000, 1_600},
35 {128_000, 20_480},
36 {400_000, 64_000},
37 {1_000_000, 160_000},
38 }
39 for _, tc := range cases {
40 a := &Agent{agentConfig: agentConfig{contextWindow: tc.window, compactRatio: defaultCompactRatio}}
41 if got := a.recentTailBudget(); got != tc.want {
42 t.Fatalf("window %d: recentTailBudget = %d, want %d", tc.window, got, tc.want)
43 }
44 }
45 }
46
47 func TestDefaultCompactRatioIsEightyPercent(t *testing.T) {
48 if defaultCompactRatio != 0.80 {
49 t.Fatalf("defaultCompactRatio = %v, want 0.80", defaultCompactRatio)
50 }
51 }
52
53 func TestDeprecatedRetentionWarningOnlyForNonDefaultValues(t *testing.T) {
54 if deprecatedContextRetentionConfigured(Options{}) ||
55 deprecatedContextRetentionConfigured(Options{RecentKeep: 2, KeepPolicy: KeepErrors}) ||
56 deprecatedContextRetentionConfigured(Options{RecentKeep: 2, KeepPolicy: KeepErrors | KeepUserMarked}) {
57 t.Fatal("default compatibility values must not warn")
58 }
59 if !deprecatedContextRetentionConfigured(Options{RecentKeep: 7}) {
60 t.Fatal("non-default recent_keep must warn")
61 }
62 if !deprecatedContextRetentionConfigured(Options{KeepPolicy: KeepUserMarked}) {
63 t.Fatal("non-default keep policy must warn")
64 }
65 }
66
67 func TestExplicitLegacyCompactRatioStillApplies(t *testing.T) {
68 a := &Agent{agentConfig: agentConfig{contextWindow: 1_000_000, compactRatio: 0.85}}
69 if got := a.compactTrigger(); got != 850_000 {
70 t.Fatalf("compactTrigger = %d, want 850000", got)
71 }
72 }
73
74 func TestLowCompactRatioTriggerAtThirtyPercent(t *testing.T) {
75 a := &Agent{agentConfig: agentConfig{contextWindow: 1_000_000, compactRatio: 0.30}}
76 if got := a.compactTrigger(); got != 300_000 {
77 t.Fatalf("compactTrigger = %d, want 300000", got)
78 }
79 }
80
81 func TestAcceptCheckpointCandidateRules(t *testing.T) {
82 a := &Agent{agentConfig: agentConfig{contextWindow: 1_000_000, compactRatio: 0.85}}
83 // 20% candidate under normal path: accept.
84 if err := a.acceptCheckpointCandidate(CompactionTriggerPressure, 850_000, 180_000); err != nil {
85 t.Fatalf("20%% candidate: %v", err)
86 }
87 // Any strictly smaller candidate below the physical ceiling is accepted;
88 // pressure convergence may summarize it once more.
89 if err := a.acceptCheckpointCandidate(CompactionTriggerPressure, 850_000, 510_000); err != nil {
90 t.Fatalf("51%% reducing candidate: %v", err)
91 }
92 // Large candidates remain valid while they shrink and stay below hard.
93 if err := a.acceptCheckpointCandidate(CompactionTriggerPressure, 900_000, 600_000); err != nil {
94 t.Fatalf("large reducing candidate: %v", err)
95 }
96 // Small but real savings are valid too.
97 if err := a.acceptCheckpointCandidate(CompactionTriggerPressure, 600_000, 550_000); err != nil {
98 t.Fatalf("small reducing candidate: %v", err)
99 }
100 // Manual below trigger: accept any reduction.
101 if err := a.acceptCheckpointCandidate(CompactionTriggerManual, 100_000, 80_000); err != nil {
102 t.Fatalf("manual below trigger: %v", err)
103 }
104 }
105
105 lines GO