Forge
csharpdeeb25a2
1using CascadeIDE.Features.Agent.Harness;
2using CascadeIDE.Models;
3using CascadeIDE.Services;
4using Xunit;
5
6namespace CascadeIDE.Tests;
7
8public sealed class ChatHarnessCoordinatorTests
9{
10 [Fact]
11 public void OnUserMessageCommitted_EmitsCheckpointAtThreshold()
12 {
13 var settings = new CascadeIdeSettings
14 {
15 Agent = new AgentSettings
16 {
17 Harness = new AgentHarnessSettings
18 {
19 CheckpointEnabled = true,
20 CheckpointThresholdUserTurns = 3,
21 CheckpointRepeatEveryUserTurns = 3,
22 },
23 },
24 };
25
26 var coord = new ChatHarnessCoordinator(() => settings, executeIdeCommand: null);
27 coord.BindSession(Guid.NewGuid());
28
29 Assert.Equal(HarnessUserTurnResult.None, coord.OnUserMessageCommitted());
30 Assert.Equal(HarnessUserTurnResult.None, coord.OnUserMessageCommitted());
31 var third = coord.OnUserMessageCommitted();
32 Assert.True(third.InjectCheckpoint);
33 Assert.Contains("harness checkpoint", third.CheckpointUserMessage, StringComparison.OrdinalIgnoreCase);
34 }
35
36 [Fact]
37 public async Task RefreshHotContext_ParsesJsonContent()
38 {
39 var settings = new CascadeIdeSettings();
40 var coord = new ChatHarnessCoordinator(
41 () => settings,
42 (_, _, _) => Task.FromResult("""{"content":"L0 stub"}"""));
43
44 await coord.OnSessionInitializedAsync();
45
46 Assert.Contains("L0 stub", coord.HotContextBlock, StringComparison.Ordinal);
47 }
48
49 [Fact]
50 public void OnThreadMessageCommitted_EmitsPreCompactAtThreshold()
51 {
52 var settings = new CascadeIdeSettings
53 {
54 Agent = new AgentSettings
55 {
56 Harness = new AgentHarnessSettings
57 {
58 CheckpointOnContextPressure = true,
59 ContextPressureThreadMessageThreshold = 5,
60 ContextPressureRepeatEveryMessages = 5,
61 },
62 },
63 };
64
65 var coord = new ChatHarnessCoordinator(() => settings, executeIdeCommand: null);
66 coord.BindSession(Guid.NewGuid());
67
68 for (var i = 1; i < 4; i++)
69 Assert.False(coord.OnThreadMessageCommitted(i).InjectPreCompact);
70
71 var fifth = coord.OnThreadMessageCommitted(5);
72 Assert.True(fifth.InjectPreCompact);
73 Assert.Contains("ADCM", fifth.PreCompactUserMessage, StringComparison.OrdinalIgnoreCase);
74 }
75
76 [Fact]
77 public void OnContextUsagePct_EmitsAtWarnThreshold()
78 {
79 var settings = new CascadeIdeSettings
80 {
81 Agent = new AgentSettings
82 {
83 Harness = new AgentHarnessSettings
84 {
85 CheckpointOnContextPressure = true,
86 ContextWarnPct = 75,
87 },
88 },
89 };
90
91 var coord = new ChatHarnessCoordinator(() => settings, executeIdeCommand: null);
92 coord.BindSession(Guid.NewGuid());
93
94 Assert.False(coord.OnContextUsagePct(7000, 10000).InjectPreCompact);
95 var atWarn = coord.OnContextUsagePct(7500, 10000);
96 Assert.True(atWarn.InjectPreCompact);
97 Assert.Contains("ADCM", atWarn.PreCompactUserMessage, StringComparison.OrdinalIgnoreCase);
98 Assert.False(coord.OnContextUsagePct(8000, 10000).InjectPreCompact);
99 Assert.True(coord.OnContextUsagePct(8500, 10000).InjectPreCompact);
100 }
101
102 [Fact]
103 public void BuildTelemetryContextBlock_IncludesStaleFlag()
104 {
105 var settings = new CascadeIdeSettings();
106 var coord = new ChatHarnessCoordinator(() => settings, executeIdeCommand: null);
107 var block = coord.BuildTelemetryContextBlock(coord.GetTelemetry(), verifyEpochUiStale: true);
108 Assert.Contains("verify_epoch_ui_stale: true", block, StringComparison.Ordinal);
109 }
110}
111
View only · write via MCP/CIDE