Forge
csharpdeeb25a2
1#nullable enable
2
3
4
5using CascadeIDE.Features.Agent.Harness;
6
7using CascadeIDE.Models;
8
9using CascadeIDE.Models.AgentChat;
10
11using CascadeIDE.ViewModels;
12
13
14
15namespace CascadeIDE.Features.Chat;
16
17
18
19public partial class ChatPanelViewModel
20
21{
22
23 internal const string DefaultTopicForkBriefTemplate =
24
25 "Цель (1 строка):\n" +
26
27 "Граница / не делаем:\n" +
28
29 "Готово когда:";
30
31
32
33 private ChatHarnessCoordinator? _harness;
34
35
36
37 public ChatHarnessCoordinator Harness =>
38
39 _harness ??= new ChatHarnessCoordinator(
40
41 () => _getCascadeSettings?.Invoke() ?? new CascadeIdeSettings(),
42
43 _executeIdeCommandForMafAgent);
44
45
46
47 private int CountMessagesInActiveThread()
48
49 {
50
51 var threadId = _activeThreadId != Guid.Empty ? _activeThreadId : _mainThreadId;
52
53 if (threadId == Guid.Empty)
54
55 return ChatMessages.Count;
56
57
58
59 var count = 0;
60
61 foreach (var msg in ChatMessages)
62
63 {
64
65 if (msg.ThreadId == threadId)
66
67 count++;
68
69 }
70
71
72
73 return count;
74
75 }
76
77
78
79 internal void ApplyTopicForkBriefToComposer()
80
81 {
82
83 var h = _getCascadeSettings?.Invoke()?.Agent.Harness;
84
85 if (h is null || !h.InjectTopicForkBrief)
86
87 return;
88
89
90
91 var template = string.IsNullOrWhiteSpace(h.TopicForkBriefTemplate)
92
93 ? DefaultTopicForkBriefTemplate
94
95 : h.TopicForkBriefTemplate.Trim();
96
97 ChatInput = template;
98
99 }
100
101
102
103 private async Task OnHarnessAfterUserMessageCommittedAsync()
104
105 {
106
107 HarnessUserTurnResult turn = HarnessUserTurnResult.None;
108
109 HarnessContextPressureResult pressure = HarnessContextPressureResult.None;
110
111
112
113 await UiScheduler.Default.InvokeAsync(() =>
114
115 {
116
117 var threadCount = CountMessagesInActiveThread();
118
119 turn = Harness.OnUserMessageCommitted();
120
121 pressure = Harness.OnThreadMessageCommitted(threadCount);
122
123 }).ConfigureAwait(false);
124
125
126
127 if (pressure.InjectPreCompact && !string.IsNullOrWhiteSpace(pressure.PreCompactUserMessage))
128
129 await InjectHarnessUserMessageAsync(pressure.PreCompactUserMessage).ConfigureAwait(false);
130
131
132
133 if (turn.InjectCheckpoint && !string.IsNullOrWhiteSpace(turn.CheckpointUserMessage))
134
135 await InjectHarnessUserMessageAsync(turn.CheckpointUserMessage).ConfigureAwait(false);
136
137 }
138
139
140
141 private async Task InjectHarnessUserMessageAsync(string prompt)
142
143 {
144
145 await UiScheduler.Default.InvokeAsync(() =>
146
147 {
148
149 var msg = new ChatMessageViewModel("user", prompt, threadId: _activeThreadId);
150
151 ChatMessages.Add(msg);
152
153 _ = PersistEventAsync(ChatHistoryEventKind.MessageAdded, ChatHistoryPayloadMapping.ToMessagePayload(msg));
154
155 RefreshChatSurfaceSnapshot();
156
157 }).ConfigureAwait(false);
158
159 }
160
161}
162
163
164
View only · write via MCP/CIDE