compact 뒤 첨부 참조가 이어지도록 요약/경계 메시지를 보강
- ContextCondenser가 오래된 메시지 구간의 첨부 파일 이름과 이미지 개수를 수집해 microcompact boundary와 요약 메시지에 함께 기록 - 요약 메시지에 AttachedFiles를 보존해 compact 이후 query view에서도 파일 참조 continuity가 유지되도록 조정 - README와 DEVELOPMENT 문서에 2026-04-12 22:36 (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:
@@ -54,6 +54,12 @@ public static class ContextCondenser
|
||||
public int PreservedToolPairs { get; init; }
|
||||
}
|
||||
|
||||
private sealed class CompactionAttachmentSummary
|
||||
{
|
||||
public required List<string> AttachedFiles { get; init; }
|
||||
public int ImageCount { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>모델별 입력 토큰 한도 (대략).</summary>
|
||||
private static int GetModelInputLimit(string service, string model)
|
||||
{
|
||||
@@ -703,17 +709,7 @@ public static class ContextCondenser
|
||||
!(m.Content ?? "").StartsWith("{\"_tool_use_blocks\"", StringComparison.Ordinal) &&
|
||||
m.MetaKind == null);
|
||||
|
||||
var attachedFiles = group
|
||||
.SelectMany(m => m.AttachedFiles ?? Enumerable.Empty<string>())
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.Select(path =>
|
||||
{
|
||||
try { return System.IO.Path.GetFileName(path); }
|
||||
catch { return path; }
|
||||
})
|
||||
.Where(name => !string.IsNullOrWhiteSpace(name))
|
||||
.Take(4)
|
||||
.ToList();
|
||||
var attachmentSummary = CollectCompactionAttachmentSummary(group, 4);
|
||||
|
||||
var lines = new List<string>
|
||||
{
|
||||
@@ -724,7 +720,8 @@ public static class ContextCondenser
|
||||
if (toolCalls > 0) lines.Add($"- 도구 호출 {toolCalls}건 정리");
|
||||
if (metaEvents > 0) lines.Add($"- 실행 메타/로그 {metaEvents}건 정리");
|
||||
if (longTexts > 0) lines.Add($"- 긴 설명/출력 {longTexts}건 축약");
|
||||
if (attachedFiles.Count > 0) lines.Add($"- 관련 파일: {string.Join(", ", attachedFiles)}");
|
||||
if (attachmentSummary.AttachedFiles.Count > 0) lines.Add($"- 관련 파일: {string.Join(", ", attachmentSummary.AttachedFiles)}");
|
||||
if (attachmentSummary.ImageCount > 0) lines.Add($"- 관련 이미지: {attachmentSummary.ImageCount}개");
|
||||
|
||||
return new ChatMessage
|
||||
{
|
||||
@@ -733,6 +730,7 @@ public static class ContextCondenser
|
||||
Timestamp = group.Last().Timestamp,
|
||||
MetaKind = "microcompact_boundary",
|
||||
MetaRunId = group.Last().MetaRunId,
|
||||
AttachedFiles = attachmentSummary.AttachedFiles.Count > 0 ? attachmentSummary.AttachedFiles : null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -747,6 +745,7 @@ public static class ContextCondenser
|
||||
var systemMsg = window.SystemMessage;
|
||||
var oldMessages = window.OldMessages;
|
||||
var recentMessages = window.RecentMessages;
|
||||
var attachmentSummary = CollectCompactionAttachmentSummary(oldMessages, 6);
|
||||
|
||||
if (oldMessages.Count < 3) return false;
|
||||
|
||||
@@ -787,8 +786,9 @@ public static class ContextCondenser
|
||||
messages.Add(new ChatMessage
|
||||
{
|
||||
Role = "user",
|
||||
Content = $"[이전 대화 요약 — {oldMessages.Count}개 메시지 압축]\n{summary}",
|
||||
Content = BuildSummaryMessageContent(oldMessages.Count, summary, attachmentSummary),
|
||||
Timestamp = DateTime.Now,
|
||||
AttachedFiles = attachmentSummary.AttachedFiles.Count > 0 ? attachmentSummary.AttachedFiles : null,
|
||||
});
|
||||
messages.Add(new ChatMessage
|
||||
{
|
||||
@@ -806,4 +806,42 @@ public static class ContextCondenser
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static CompactionAttachmentSummary CollectCompactionAttachmentSummary(IEnumerable<ChatMessage> messages, int maxFiles)
|
||||
{
|
||||
var attachedFiles = messages
|
||||
.SelectMany(m => m.AttachedFiles ?? Enumerable.Empty<string>())
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.Select(path =>
|
||||
{
|
||||
try { return System.IO.Path.GetFileName(path); }
|
||||
catch { return path; }
|
||||
})
|
||||
.Where(name => !string.IsNullOrWhiteSpace(name))
|
||||
.Take(Math.Max(1, maxFiles))
|
||||
.ToList();
|
||||
|
||||
var imageCount = messages.Sum(m => m.Images?.Count ?? 0);
|
||||
return new CompactionAttachmentSummary
|
||||
{
|
||||
AttachedFiles = attachedFiles,
|
||||
ImageCount = imageCount,
|
||||
};
|
||||
}
|
||||
|
||||
private static string BuildSummaryMessageContent(int oldMessageCount, string summary, CompactionAttachmentSummary attachmentSummary)
|
||||
{
|
||||
var lines = new List<string>
|
||||
{
|
||||
$"[이전 대화 요약 — {oldMessageCount}개 메시지 압축]",
|
||||
summary.Trim()
|
||||
};
|
||||
|
||||
if (attachmentSummary.AttachedFiles.Count > 0)
|
||||
lines.Add($"참고 파일: {string.Join(", ", attachmentSummary.AttachedFiles)}");
|
||||
if (attachmentSummary.ImageCount > 0)
|
||||
lines.Add($"참고 이미지: {attachmentSummary.ImageCount}개");
|
||||
|
||||
return string.Join("\n", lines.Where(x => !string.IsNullOrWhiteSpace(x)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user