컨텍스트 전송 뷰와 압축 트리거를 claw-code 기준으로 정리
claw-code의 query.ts, autoCompact.ts, sessionMemoryCompact.ts 흐름을 참고해 AX Agent의 컨텍스트 관리와 압축 동작을 더 가깝게 맞췄다. - AgentQueryContextBuilder를 추가해 저장된 전체 대화와 실제 LLM 전송용 query view를 분리 - compact boundary 이후만 전송하고 tool_result/tool_use 짝이 끊기지 않도록 start index를 보정 - 오래된 tool_result는 query view에서만 별도 budget으로 축약하도록 조정 - ContextCondenser의 자동 압축 시작점을 effective context window, summary reserve, buffer 기준으로 재계산 - 미사용 입력 높이 캐시 필드를 제거해 빌드 경고를 해소 - README.md, docs/DEVELOPMENT.md에 2026-04-12 21:34 (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:
@@ -13,7 +13,6 @@ namespace AxCopilot.Views;
|
||||
public partial class ChatWindow
|
||||
{
|
||||
// 레이아웃 재계산 억제용 캐시: 동일한 높이면 WPF measure/arrange 생략
|
||||
private double _cachedInputBoxHeight = -1;
|
||||
private int _cachedInputBoxMaxLines = -1;
|
||||
|
||||
private void UpdateInputBoxHeight()
|
||||
@@ -21,8 +20,6 @@ public partial class ChatWindow
|
||||
if (InputBox == null)
|
||||
return;
|
||||
|
||||
var text = InputBox.Text ?? string.Empty;
|
||||
var explicitLineCount = 1 + text.Count(ch => ch == '\n');
|
||||
var displayMode = (_settings.Settings.Llm.AgentUiExpressionLevel ?? "balanced").Trim().ToLowerInvariant();
|
||||
if (displayMode is not ("rich" or "balanced" or "simple"))
|
||||
displayMode = "balanced";
|
||||
@@ -33,25 +30,18 @@ public partial class ChatWindow
|
||||
"simple" => 4,
|
||||
_ => 5,
|
||||
};
|
||||
const double baseHeight = 42;
|
||||
const double lineStep = 22;
|
||||
var visibleLines = Math.Clamp(explicitLineCount, 1, maxLines);
|
||||
var targetHeight = baseHeight + ((visibleLines - 1) * lineStep);
|
||||
var needsScroll = explicitLineCount > maxLines;
|
||||
|
||||
// 값이 바뀐 경우에만 WPF 속성 쓰기 (매 키입력마다 레이아웃 통과 방지)
|
||||
if (Math.Abs(targetHeight - _cachedInputBoxHeight) < 0.5 && maxLines == _cachedInputBoxMaxLines)
|
||||
// MaxLines로 시각적 줄 수 제한 (TextWrapping에 의한 자동 줄바꿈 포함)
|
||||
// Height를 Auto로 두고 MaxLines + MaxHeight가 자연스럽게 크기를 제어
|
||||
if (maxLines == _cachedInputBoxMaxLines)
|
||||
return;
|
||||
|
||||
_cachedInputBoxHeight = targetHeight;
|
||||
_cachedInputBoxMaxLines = maxLines;
|
||||
|
||||
InputBox.MinLines = 1;
|
||||
InputBox.MaxLines = maxLines;
|
||||
InputBox.Height = targetHeight;
|
||||
InputBox.VerticalScrollBarVisibility = needsScroll
|
||||
? ScrollBarVisibility.Auto
|
||||
: ScrollBarVisibility.Disabled;
|
||||
InputBox.Height = double.NaN; // Auto — WPF가 TextWrapping + MaxLines 기반으로 자동 계산
|
||||
InputBox.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
|
||||
}
|
||||
|
||||
private string BuildComposerDraftText()
|
||||
@@ -89,13 +79,44 @@ public partial class ChatWindow
|
||||
if (InputBox == null)
|
||||
return;
|
||||
|
||||
// 코워크/코드 탭에서 작업 폴더 미지정 시 전송 차단
|
||||
if (_activeTab is "Cowork" or "Code" && string.IsNullOrWhiteSpace(GetCurrentWorkFolder()))
|
||||
{
|
||||
HighlightFolderSelectButton();
|
||||
return;
|
||||
}
|
||||
|
||||
var text = BuildComposerDraftText();
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return;
|
||||
|
||||
// 현재 탭이 스트리밍 중일 때만 우선순위를 "next"로 낮춤 — 다른 탭 스트리밍은 무관
|
||||
if (_streamingTabs.Contains(_activeTab) && string.Equals(priority, "now", StringComparison.OrdinalIgnoreCase))
|
||||
priority = "next";
|
||||
// ── 실행 중 메시지 주입 (Claude Code 스타일) ──
|
||||
// 현재 탭이 스트리밍 중이면 에이전트 루프에 직접 메시지 주입
|
||||
if (_streamingTabs.Contains(_activeTab))
|
||||
{
|
||||
HideSlashChip(restoreText: false);
|
||||
ClearPromptCardPlaceholder();
|
||||
|
||||
// 에이전트 루프에 메시지 주입
|
||||
if (_agentLoops.TryGetValue(_activeTab, out var activeLoop))
|
||||
activeLoop.InjectUserMessage(text);
|
||||
|
||||
// 현재 대화에 사용자 메시지 기록
|
||||
lock (_convLock)
|
||||
{
|
||||
_currentConversation?.Messages.Add(new ChatMessage { Role = "user", Content = text });
|
||||
}
|
||||
|
||||
// UI에 사용자 메시지 버블 표시
|
||||
RenderMessages();
|
||||
|
||||
InputBox.Clear();
|
||||
InputBox.Focus();
|
||||
UpdateInputBoxHeight();
|
||||
|
||||
ShowToast("메시지가 실행 중인 에이전트에 전달되었습니다.", "\uE8FB");
|
||||
return;
|
||||
}
|
||||
|
||||
HideSlashChip(restoreText: false);
|
||||
ClearPromptCardPlaceholder();
|
||||
@@ -248,7 +269,7 @@ public partial class ChatWindow
|
||||
var stateIcon = new TextBlock
|
||||
{
|
||||
Text = GetDraftStateIcon(item),
|
||||
FontFamily = new FontFamily("Segoe MDL2 Assets"),
|
||||
FontFamily = s_segoeIconFont,
|
||||
FontSize = 11,
|
||||
Foreground = GetDraftStateIconBrush(item),
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
@@ -326,7 +347,7 @@ public partial class ChatWindow
|
||||
new TextBlock
|
||||
{
|
||||
Text = kindIcon,
|
||||
FontFamily = new FontFamily("Segoe MDL2 Assets"),
|
||||
FontFamily = s_segoeIconFont,
|
||||
FontSize = 10,
|
||||
Foreground = foreground,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
@@ -352,7 +373,7 @@ public partial class ChatWindow
|
||||
Content = new TextBlock
|
||||
{
|
||||
Text = icon,
|
||||
FontFamily = new FontFamily("Segoe MDL2 Assets"),
|
||||
FontFamily = s_segoeIconFont,
|
||||
FontSize = 11,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
|
||||
Reference in New Issue
Block a user