컨텍스트 압축 이력 재노출과 compact 비교 기반 보강
Some checks failed
Release Gate / gate (push) Has been cancelled

- AX Agent 하단 컨텍스트 카드 툴팁에 최근 압축 시각, 자동/수동 여부, 압축 전후 토큰, 절감량을 다시 볼 수 있는 compact 이력을 추가함
- 수동 /compact와 전송 전 자동 컨텍스트 압축이 모두 같은 compaction 통계 기록 경로를 사용하도록 정리해 결과를 이후 UI에서도 확인할 수 있게 보강함
- README와 docs/DEVELOPMENT.md에 2026-04-04 23:28 (KST) 기준 이력을 반영함
- 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ (경고 0 / 오류 0)
This commit is contained in:
2026-04-04 23:29:45 +09:00
parent d883ccf9e6
commit 45779f8c6f
3 changed files with 40 additions and 1 deletions

View File

@@ -95,6 +95,10 @@ public partial class ChatWindow : Window
private StackPanel? _selectedMessageActionBar;
private Border? _selectedMessageBorder;
private bool _isRefreshingFromSettings;
private int? _lastCompactionBeforeTokens;
private int? _lastCompactionAfterTokens;
private DateTime? _lastCompactionAt;
private bool _lastCompactionWasAutomatic;
private void ApplyQuickActionVisual(Button button, bool active, string activeBg, string activeFg)
{
if (button?.Content is not string text)
@@ -6507,6 +6511,7 @@ public partial class ChatWindow : Window
true,
CancellationToken.None);
var afterTokens = Services.TokenEstimator.EstimateMessages(working);
RecordCompactionStats(beforeTokens, afterTokens, wasAutomatic: false);
if (condensed)
{
@@ -6543,6 +6548,7 @@ public partial class ChatWindow : Window
if (StatusTokens != null)
StatusTokens.Text = $"컨텍스트 {Services.TokenEstimator.Format(beforeTokens)} → {Services.TokenEstimator.Format(afterTokens)}";
SetStatus(condensed ? "컨텍스트 압축 완료" : "압축할 컨텍스트 없음", spinning: false);
RefreshContextUsageVisual();
RefreshConversationList();
UpdateTaskSummaryIndicators();
}
@@ -8075,6 +8081,7 @@ public partial class ChatWindow : Window
// ── 전송 전 컨텍스트 사전 압축 ──
{
var llm = _settings.Settings.Llm;
var beforeCompactTokens = Services.TokenEstimator.EstimateMessages(sendMessages);
var condensed = await ContextCondenser.CondenseIfNeededAsync(
sendMessages,
_llm,
@@ -8084,7 +8091,12 @@ public partial class ChatWindow : Window
false,
_streamCts!.Token);
if (condensed)
{
var afterCompactTokens = Services.TokenEstimator.EstimateMessages(sendMessages);
RecordCompactionStats(beforeCompactTokens, afterCompactTokens, wasAutomatic: true);
SetStatus("컨텍스트를 사전 정리했습니다", spinning: true);
RefreshContextUsageVisual();
}
}
// ── 자동 모델 라우팅 ──
@@ -16481,12 +16493,20 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
TokenUsageSummaryText.Text = $"컨텍스트 {percentText}";
TokenUsageHintText.Text = $"{Services.TokenEstimator.Format(currentTokens)} / {Services.TokenEstimator.Format(maxContextTokens)}";
CompactNowLabel.Text = compactLabel;
var compactHistory = _lastCompactionAt.HasValue && _lastCompactionBeforeTokens.HasValue && _lastCompactionAfterTokens.HasValue
? $"\n최근 압축: {(_lastCompactionWasAutomatic ? "" : "")} · {_lastCompactionAt.Value:HH:mm:ss}\n" +
$"절감: {_lastCompactionBeforeTokens.Value:N0} → {_lastCompactionAfterTokens.Value:N0} tokens " +
$"(-{Math.Max(0, _lastCompactionBeforeTokens.Value - _lastCompactionAfterTokens.Value):N0}, " +
$"{Services.TokenEstimator.Format(_lastCompactionBeforeTokens.Value)} → {Services.TokenEstimator.Format(_lastCompactionAfterTokens.Value)})"
: "";
TokenUsageCard.ToolTip =
$"상태: {summary}\n" +
$"사용량: {currentTokens:N0} / {maxContextTokens:N0} tokens ({percentText})\n" +
$"간단 표기: {Services.TokenEstimator.Format(currentTokens)} / {Services.TokenEstimator.Format(maxContextTokens)}\n" +
$"자동 압축 시작: {triggerPercent}%\n" +
$"현재 입력 초안 포함";
$"현재 입력 초안 포함" +
compactHistory;
UpdateCircularUsageArc(TokenUsageArc, usageRatio, 18, 18, 14);
PositionThresholdMarker(TokenUsageThresholdMarker, triggerRatio, 18, 18, 14, 3);
@@ -16535,6 +16555,14 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
centerY + radius * Math.Sin(radians));
}
private void RecordCompactionStats(int beforeTokens, int afterTokens, bool wasAutomatic)
{
_lastCompactionBeforeTokens = Math.Max(0, beforeTokens);
_lastCompactionAfterTokens = Math.Max(0, afterTokens);
_lastCompactionAt = DateTime.Now;
_lastCompactionWasAutomatic = wasAutomatic;
}
private void ScheduleGitBranchRefresh(int delayMs = 400)
{
if (BtnGitBranch == null)