- claude-code의 post-compaction 플래그 흐름을 참고해 compact 직후 첫 응답을 별도로 추적하고 대화 단위 후속 사용량을 집계함 - ChatConversation에 pending post-compaction, 응답 회수, prompt/completion token 누적 필드를 추가하고 AX Agent 컨텍스트 카드 hover에 표시함 - README 및 docs/DEVELOPMENT.md에 2026-04-04 23:47 (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:
@@ -175,6 +175,18 @@ public class ChatConversation
|
||||
|
||||
[JsonPropertyName("lastCompactionStageSummary")]
|
||||
public string? LastCompactionStageSummary { get; set; }
|
||||
|
||||
[JsonPropertyName("pendingPostCompaction")]
|
||||
public bool PendingPostCompaction { get; set; }
|
||||
|
||||
[JsonPropertyName("postCompactionResponseCount")]
|
||||
public int PostCompactionResponseCount { get; set; }
|
||||
|
||||
[JsonPropertyName("postCompactionPromptTokens")]
|
||||
public int PostCompactionPromptTokens { get; set; }
|
||||
|
||||
[JsonPropertyName("postCompactionCompletionTokens")]
|
||||
public int PostCompactionCompletionTokens { get; set; }
|
||||
}
|
||||
|
||||
public class ChatAgentRunRecord
|
||||
|
||||
@@ -107,6 +107,10 @@ public partial class ChatWindow : Window
|
||||
private int _sessionMemoryCompactionCount;
|
||||
private int _sessionMicrocompactBoundaryCount;
|
||||
private int _sessionSnipCompactionCount;
|
||||
private bool _pendingPostCompaction;
|
||||
private int _sessionPostCompactionResponseCount;
|
||||
private int _sessionPostCompactionPromptTokens;
|
||||
private int _sessionPostCompactionCompletionTokens;
|
||||
private void ApplyQuickActionVisual(Button button, bool active, string activeBg, string activeFg)
|
||||
{
|
||||
if (button?.Content is not string text)
|
||||
@@ -1732,6 +1736,10 @@ public partial class ChatWindow : Window
|
||||
_sessionMemoryCompactionCount = conv?.SessionMemoryCompactionCount ?? 0;
|
||||
_sessionMicrocompactBoundaryCount = conv?.MicrocompactBoundaryCount ?? 0;
|
||||
_sessionSnipCompactionCount = conv?.SnipCompactionCount ?? 0;
|
||||
_pendingPostCompaction = conv?.PendingPostCompaction ?? false;
|
||||
_sessionPostCompactionResponseCount = conv?.PostCompactionResponseCount ?? 0;
|
||||
_sessionPostCompactionPromptTokens = conv?.PostCompactionPromptTokens ?? 0;
|
||||
_sessionPostCompactionCompletionTokens = conv?.PostCompactionCompletionTokens ?? 0;
|
||||
_lastCompactionAt = conv?.LastCompactionAt;
|
||||
_lastCompactionWasAutomatic = conv?.LastCompactionWasAutomatic ?? false;
|
||||
_lastCompactionBeforeTokens = conv?.LastCompactionBeforeTokens;
|
||||
@@ -10939,10 +10947,12 @@ public partial class ChatWindow : Window
|
||||
? _agentCumulativeOutputTokens
|
||||
: usage?.CompletionTokens ?? 0;
|
||||
|
||||
var wasPostCompactionResponse = _pendingPostCompaction;
|
||||
if (displayInput > 0 || displayOutput > 0)
|
||||
{
|
||||
UpdateStatusTokens(displayInput, displayOutput);
|
||||
Services.UsageStatisticsService.RecordTokens(displayInput, displayOutput);
|
||||
ConsumePostCompactionUsageIfNeeded(displayInput, displayOutput);
|
||||
}
|
||||
string tokenText;
|
||||
if (displayInput > 0 || displayOutput > 0)
|
||||
@@ -10952,9 +10962,10 @@ public partial class ChatWindow : Window
|
||||
else
|
||||
tokenText = $"~{FormatTokenCount(EstimateTokenCount(finalContent))} tokens";
|
||||
|
||||
var postCompactSuffix = wasPostCompactionResponse ? " · compact 직후" : "";
|
||||
var metaText = new TextBlock
|
||||
{
|
||||
Text = $"{elapsedText} · {tokenText}",
|
||||
Text = $"{elapsedText} · {tokenText}{postCompactSuffix}",
|
||||
FontSize = 9.5,
|
||||
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
|
||||
HorizontalAlignment = HorizontalAlignment.Right,
|
||||
@@ -16532,6 +16543,11 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
|
||||
$"세션 절감: {Services.TokenEstimator.Format(_sessionCompactionSavedTokens)} tokens\n" +
|
||||
$"세션 메모리 {_sessionMemoryCompactionCount:N0}회 · 경계 {_sessionMicrocompactBoundaryCount:N0}건 · snip {_sessionSnipCompactionCount:N0}건"
|
||||
: "";
|
||||
var postCompactionUsage = _sessionPostCompactionResponseCount > 0
|
||||
? $"\ncompact 이후 응답: {_sessionPostCompactionResponseCount:N0}회\n" +
|
||||
$"compact 이후 사용량: {Services.TokenEstimator.Format(_sessionPostCompactionPromptTokens)} + {Services.TokenEstimator.Format(_sessionPostCompactionCompletionTokens)} = {Services.TokenEstimator.Format(_sessionPostCompactionPromptTokens + _sessionPostCompactionCompletionTokens)} tokens"
|
||||
: "";
|
||||
var pendingPostCompaction = _pendingPostCompaction ? "\ncompact 후 첫 응답 대기 중" : "";
|
||||
|
||||
TokenUsageCard.ToolTip =
|
||||
$"상태: {summary}\n" +
|
||||
@@ -16540,7 +16556,9 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
|
||||
$"자동 압축 시작: {triggerPercent}%\n" +
|
||||
$"현재 입력 초안 포함" +
|
||||
compactHistory +
|
||||
compactSession;
|
||||
compactSession +
|
||||
postCompactionUsage +
|
||||
pendingPostCompaction;
|
||||
|
||||
UpdateCircularUsageArc(TokenUsageArc, usageRatio, 18, 18, 14);
|
||||
PositionThresholdMarker(TokenUsageThresholdMarker, triggerRatio, 18, 18, 14, 3);
|
||||
@@ -16605,6 +16623,7 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
|
||||
_sessionMemoryCompactionCount += result.SessionMemoryApplied ? 1 : 0;
|
||||
_sessionMicrocompactBoundaryCount += result.MicrocompactBoundaryCount;
|
||||
_sessionSnipCompactionCount += result.SnippedMessageCount + result.CollapsedBoundaryCount;
|
||||
_pendingPostCompaction = true;
|
||||
if (wasAutomatic)
|
||||
_sessionAutomaticCompactionCount++;
|
||||
else
|
||||
@@ -16627,6 +16646,29 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
|
||||
conv.LastCompactionBeforeTokens = beforeTokens;
|
||||
conv.LastCompactionAfterTokens = afterTokens;
|
||||
conv.LastCompactionStageSummary = _lastCompactionStageSummary;
|
||||
conv.PendingPostCompaction = true;
|
||||
try { _storage.Save(conv); } catch { }
|
||||
}
|
||||
|
||||
private void ConsumePostCompactionUsageIfNeeded(int promptTokens, int completionTokens)
|
||||
{
|
||||
if (!_pendingPostCompaction)
|
||||
return;
|
||||
|
||||
_pendingPostCompaction = false;
|
||||
_sessionPostCompactionResponseCount++;
|
||||
_sessionPostCompactionPromptTokens += Math.Max(0, promptTokens);
|
||||
_sessionPostCompactionCompletionTokens += Math.Max(0, completionTokens);
|
||||
|
||||
ChatConversation? conv;
|
||||
lock (_convLock) conv = _currentConversation;
|
||||
if (conv == null)
|
||||
return;
|
||||
|
||||
conv.PendingPostCompaction = false;
|
||||
conv.PostCompactionResponseCount = _sessionPostCompactionResponseCount;
|
||||
conv.PostCompactionPromptTokens = _sessionPostCompactionPromptTokens;
|
||||
conv.PostCompactionCompletionTokens = _sessionPostCompactionCompletionTokens;
|
||||
try { _storage.Save(conv); } catch { }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user