- 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:
@@ -384,6 +384,10 @@ ow + toggle 시각 언어로 통일했습니다.
|
|||||||
- AX Agent 설정 저장 경로에서 표현 수준을 `rich`로 고정 덮어쓰던 처리도 제거해, 사용자가 선택한 `풍부하게 / 적절하게 / 간단하게` 값이 다른 설정 저장 흐름에서도 유지되도록 보정했습니다.
|
- AX Agent 설정 저장 경로에서 표현 수준을 `rich`로 고정 덮어쓰던 처리도 제거해, 사용자가 선택한 `풍부하게 / 적절하게 / 간단하게` 값이 다른 설정 저장 흐름에서도 유지되도록 보정했습니다.
|
||||||
- DraftQueue 패널은 실행 중 / 다음 작업 / 보류 / 완료 / 실패를 개별 섹션으로 나눠 현재 실행 상태와 최근 결과를 더 빠르게 파악할 수 있도록 재구성했습니다.
|
- DraftQueue 패널은 실행 중 / 다음 작업 / 보류 / 완료 / 실패를 개별 섹션으로 나눠 현재 실행 상태와 최근 결과를 더 빠르게 파악할 수 있도록 재구성했습니다.
|
||||||
- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\` 경고 0 / 오류 0
|
- 검증: `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
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -4076,3 +4076,10 @@ ow + toggle 시각 언어로 다시 정렬했다.
|
|||||||
- AX Agent 설정 저장 경로와 구형 Agent 설정창에서 표현 수준을 무조건 `rich`로 덮어쓰던 코드를 제거해, 사용자가 선택한 `풍부하게 / 적절하게 / 간단하게` 값이 다른 설정 흐름에서도 유지되도록 수정했다.
|
- AX Agent 설정 저장 경로와 구형 Agent 설정창에서 표현 수준을 무조건 `rich`로 덮어쓰던 코드를 제거해, 사용자가 선택한 `풍부하게 / 적절하게 / 간단하게` 값이 다른 설정 흐름에서도 유지되도록 수정했다.
|
||||||
- DraftQueue 패널은 기존 `실행 대기 / 최근 결과` 묶음에서 `실행 중 / 다음 작업 / 보류 / 완료 / 실패` 개별 섹션 구조로 재편해 queue state가 많은 경우에도 현재 진행, 다음 실행, 재시도 대기, 완료/실패 이력을 더 빠르게 구분할 수 있게 했다.
|
- DraftQueue 패널은 기존 `실행 대기 / 최근 결과` 묶음에서 `실행 중 / 다음 작업 / 보류 / 완료 / 실패` 개별 섹션 구조로 재편해 queue state가 많은 경우에도 현재 진행, 다음 실행, 재시도 대기, 완료/실패 이력을 더 빠르게 구분할 수 있게 했다.
|
||||||
- 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify\ -p:IntermediateOutputPath=obj\verify\ (경고 0 / 오류 0)
|
- 검증: 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)
|
||||||
|
|||||||
@@ -95,6 +95,10 @@ public partial class ChatWindow : Window
|
|||||||
private StackPanel? _selectedMessageActionBar;
|
private StackPanel? _selectedMessageActionBar;
|
||||||
private Border? _selectedMessageBorder;
|
private Border? _selectedMessageBorder;
|
||||||
private bool _isRefreshingFromSettings;
|
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)
|
private void ApplyQuickActionVisual(Button button, bool active, string activeBg, string activeFg)
|
||||||
{
|
{
|
||||||
if (button?.Content is not string text)
|
if (button?.Content is not string text)
|
||||||
@@ -6507,6 +6511,7 @@ public partial class ChatWindow : Window
|
|||||||
true,
|
true,
|
||||||
CancellationToken.None);
|
CancellationToken.None);
|
||||||
var afterTokens = Services.TokenEstimator.EstimateMessages(working);
|
var afterTokens = Services.TokenEstimator.EstimateMessages(working);
|
||||||
|
RecordCompactionStats(beforeTokens, afterTokens, wasAutomatic: false);
|
||||||
|
|
||||||
if (condensed)
|
if (condensed)
|
||||||
{
|
{
|
||||||
@@ -6543,6 +6548,7 @@ public partial class ChatWindow : Window
|
|||||||
if (StatusTokens != null)
|
if (StatusTokens != null)
|
||||||
StatusTokens.Text = $"컨텍스트 {Services.TokenEstimator.Format(beforeTokens)} → {Services.TokenEstimator.Format(afterTokens)}";
|
StatusTokens.Text = $"컨텍스트 {Services.TokenEstimator.Format(beforeTokens)} → {Services.TokenEstimator.Format(afterTokens)}";
|
||||||
SetStatus(condensed ? "컨텍스트 압축 완료" : "압축할 컨텍스트 없음", spinning: false);
|
SetStatus(condensed ? "컨텍스트 압축 완료" : "압축할 컨텍스트 없음", spinning: false);
|
||||||
|
RefreshContextUsageVisual();
|
||||||
RefreshConversationList();
|
RefreshConversationList();
|
||||||
UpdateTaskSummaryIndicators();
|
UpdateTaskSummaryIndicators();
|
||||||
}
|
}
|
||||||
@@ -8075,6 +8081,7 @@ public partial class ChatWindow : Window
|
|||||||
// ── 전송 전 컨텍스트 사전 압축 ──
|
// ── 전송 전 컨텍스트 사전 압축 ──
|
||||||
{
|
{
|
||||||
var llm = _settings.Settings.Llm;
|
var llm = _settings.Settings.Llm;
|
||||||
|
var beforeCompactTokens = Services.TokenEstimator.EstimateMessages(sendMessages);
|
||||||
var condensed = await ContextCondenser.CondenseIfNeededAsync(
|
var condensed = await ContextCondenser.CondenseIfNeededAsync(
|
||||||
sendMessages,
|
sendMessages,
|
||||||
_llm,
|
_llm,
|
||||||
@@ -8084,7 +8091,12 @@ public partial class ChatWindow : Window
|
|||||||
false,
|
false,
|
||||||
_streamCts!.Token);
|
_streamCts!.Token);
|
||||||
if (condensed)
|
if (condensed)
|
||||||
|
{
|
||||||
|
var afterCompactTokens = Services.TokenEstimator.EstimateMessages(sendMessages);
|
||||||
|
RecordCompactionStats(beforeCompactTokens, afterCompactTokens, wasAutomatic: true);
|
||||||
SetStatus("컨텍스트를 사전 정리했습니다", spinning: true);
|
SetStatus("컨텍스트를 사전 정리했습니다", spinning: true);
|
||||||
|
RefreshContextUsageVisual();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 자동 모델 라우팅 ──
|
// ── 자동 모델 라우팅 ──
|
||||||
@@ -16481,12 +16493,20 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
|
|||||||
TokenUsageSummaryText.Text = $"컨텍스트 {percentText}";
|
TokenUsageSummaryText.Text = $"컨텍스트 {percentText}";
|
||||||
TokenUsageHintText.Text = $"{Services.TokenEstimator.Format(currentTokens)} / {Services.TokenEstimator.Format(maxContextTokens)}";
|
TokenUsageHintText.Text = $"{Services.TokenEstimator.Format(currentTokens)} / {Services.TokenEstimator.Format(maxContextTokens)}";
|
||||||
CompactNowLabel.Text = compactLabel;
|
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 =
|
TokenUsageCard.ToolTip =
|
||||||
$"상태: {summary}\n" +
|
$"상태: {summary}\n" +
|
||||||
$"사용량: {currentTokens:N0} / {maxContextTokens:N0} tokens ({percentText})\n" +
|
$"사용량: {currentTokens:N0} / {maxContextTokens:N0} tokens ({percentText})\n" +
|
||||||
$"간단 표기: {Services.TokenEstimator.Format(currentTokens)} / {Services.TokenEstimator.Format(maxContextTokens)}\n" +
|
$"간단 표기: {Services.TokenEstimator.Format(currentTokens)} / {Services.TokenEstimator.Format(maxContextTokens)}\n" +
|
||||||
$"자동 압축 시작: {triggerPercent}%\n" +
|
$"자동 압축 시작: {triggerPercent}%\n" +
|
||||||
$"현재 입력 초안 포함";
|
$"현재 입력 초안 포함" +
|
||||||
|
compactHistory;
|
||||||
|
|
||||||
UpdateCircularUsageArc(TokenUsageArc, usageRatio, 18, 18, 14);
|
UpdateCircularUsageArc(TokenUsageArc, usageRatio, 18, 18, 14);
|
||||||
PositionThresholdMarker(TokenUsageThresholdMarker, triggerRatio, 18, 18, 14, 3);
|
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));
|
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)
|
private void ScheduleGitBranchRefresh(int delayMs = 400)
|
||||||
{
|
{
|
||||||
if (BtnGitBranch == null)
|
if (BtnGitBranch == null)
|
||||||
|
|||||||
Reference in New Issue
Block a user