컨텍스트 압축 이력 재노출과 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

@@ -384,6 +384,10 @@ ow + toggle 시각 언어로 통일했습니다.
- AX Agent 설정 저장 경로에서 표현 수준을 `rich`로 고정 덮어쓰던 처리도 제거해, 사용자가 선택한 `풍부하게 / 적절하게 / 간단하게` 값이 다른 설정 저장 흐름에서도 유지되도록 보정했습니다.
- DraftQueue 패널은 실행 중 / 다음 작업 / 보류 / 완료 / 실패를 개별 섹션으로 나눠 현재 실행 상태와 최근 결과를 더 빠르게 파악할 수 있도록 재구성했습니다.
- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\` 경고 0 / 오류 0
- 업데이트: 2026-04-04 23:28 (KST)
- AX Agent 하단 컨텍스트 카드 툴팁에 최근 압축 이력을 추가해 마지막 자동/수동 compact 시각, 압축 전후 토큰, 실제 절감량을 다시 확인할 수 있게 했습니다.
- 수동 `/compact` 실행과 전송 전 자동 컨텍스트 압축 모두 같은 compaction 통계 경로를 타도록 맞춰, compact 결과를 일회성 토스트가 아니라 이후 UI에서도 계속 확인할 수 있도록 보강했습니다.
- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\` 경고 0 / 오류 0
---

View File

@@ -4076,3 +4076,10 @@ ow + toggle 시각 언어로 다시 정렬했다.
- AX Agent 설정 저장 경로와 구형 Agent 설정창에서 표현 수준을 무조건 `rich`로 덮어쓰던 코드를 제거해, 사용자가 선택한 `풍부하게 / 적절하게 / 간단하게` 값이 다른 설정 흐름에서도 유지되도록 수정했다.
- DraftQueue 패널은 기존 `실행 대기 / 최근 결과` 묶음에서 `실행 중 / 다음 작업 / 보류 / 완료 / 실패` 개별 섹션 구조로 재편해 queue state가 많은 경우에도 현재 진행, 다음 실행, 재시도 대기, 완료/실패 이력을 더 빠르게 구분할 수 있게 했다.
- 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify\ -p:IntermediateOutputPath=obj\verify\ (경고 0 / 오류 0)
### 2026-04-04 추가 진행 기록 (연속 실행 77차: compact 결과 재노출과 압축 비교 준비)
- 업데이트: 2026-04-04 23:28 (KST)
- AX Agent 하단 컨텍스트 카드의 툴팁에 최근 compact 이력을 추가해 마지막 자동/수동 압축 시각, 압축 전후 토큰 수, 절감량을 이후에도 다시 확인할 수 있게 보강했다.
- 수동 `/compact`와 전송 전 자동 컨텍스트 압축이 모두 같은 `RecordCompactionStats(...)` 경로를 사용하도록 맞춰, 압축 결과가 일회성 상태 메시지에만 머물지 않고 UI에서 재참조 가능하도록 정리했다.
- 이번 라운드부터 `claude-code`의 compact 소스를 기준으로 `session memory compaction → microcompact → context collapse/snip → autocompact → post-compaction 계측` 흐름을 AX 기준과 비교 분석할 준비를 진행했다.
- 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify\ -p:IntermediateOutputPath=obj\verify\ (경고 0 / 오류 0)

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)