AX Agent 채팅 UI 백업 및 claw-code 기준 엔진 재정렬
Some checks failed
Release Gate / gate (push) Has been cancelled

- ChatWindow 현재 UI와 엔진 기준본을 etc/chat-ui-backup/2026-04-05-1215에 백업해 회귀 비교 지점을 확보함

- 메시지 컬럼과 컴포저 폭을 claw-code식 단일 축으로 다시 맞추고 입력 셸을 안정적인 하단 컬럼 구조로 정리함

- 입력창 높이를 실제 줄바꿈 수 기준으로 다시 계산해 전송 후 높이가 남는 버그를 줄임

- 메시지 편집/피드백 후 재생성 경로의 직접 UI 버블 주입을 제거하고 RenderMessages 중심으로 통합함

- SendRegenerateAsync가 Cowork/Code에서 ResolveExecutionMode와 RunAgentLoopAsync를 타도록 바꿔 재생성도 동일 엔진 축으로 정렬함

- 검증: 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-05 12:19:20 +09:00
parent f82cfc4541
commit 3ed454a98c
7 changed files with 29653 additions and 363 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -5288,16 +5288,8 @@ public partial class ChatWindow : Window
}
}
// UI에서 편집된 버블 이후 모두 제거
while (MessagePanel.Children.Count > bubbleIndex + 1)
MessagePanel.Children.RemoveAt(MessagePanel.Children.Count - 1);
// 편집된 메시지를 새 버블로 교체
MessagePanel.Children.RemoveAt(bubbleIndex);
AddMessageBubble("user", newText, animate: false);
// 마지막 위치에 삽입되도록 조정 (AddMessageBubble은 끝에 추가됨)
// bubbleIndex가 끝이 아니면 이동 — 이 경우 이후가 다 제거되었으므로 끝에 추가됨
RenderMessages(preserveViewport: true);
AutoScrollIfNeeded();
// AI 재응답
await SendRegenerateAsync(conv);
@@ -5723,10 +5715,14 @@ public partial class ChatWindow : Window
"simple" => 4,
_ => 5,
};
const double baseHeight = 42;
const double lineStep = 22;
var visibleLines = Math.Clamp(explicitLineCount, 1, maxLines);
var targetHeight = baseHeight + ((visibleLines - 1) * lineStep);
InputBox.MinLines = 1;
InputBox.MaxLines = maxLines;
InputBox.SetCurrentValue(TextBox.HeightProperty, double.NaN);
InputBox.Height = targetHeight;
InputBox.VerticalScrollBarVisibility = explicitLineCount > maxLines
? ScrollBarVisibility.Auto
: ScrollBarVisibility.Disabled;
@@ -10961,8 +10957,8 @@ public partial class ChatWindow : Window
}
}
// 피드백 메시지 UI 표시
AddMessageBubble("user", $"[수정 요청] {feedback}", true);
RenderMessages(preserveViewport: true);
AutoScrollIfNeeded();
// 재전송
await SendRegenerateAsync(conv);
@@ -10970,7 +10966,9 @@ public partial class ChatWindow : Window
private async Task SendRegenerateAsync(ChatConversation conv)
{
var runTab = NormalizeTabName(conv.Tab);
_isStreaming = true;
_streamRunTab = runTab;
BtnSend.IsEnabled = false;
BtnSend.Visibility = Visibility.Collapsed;
BtnStop.Visibility = Visibility.Visible;
@@ -10989,12 +10987,31 @@ public partial class ChatWindow : Window
try
{
List<ChatMessage> sendMessages;
lock (_convLock) sendMessages = conv.Messages.ToList();
if (!string.IsNullOrEmpty(conv.SystemCommand))
sendMessages.Insert(0, new ChatMessage { Role = "system", Content = conv.SystemCommand });
var coworkSystem = string.Equals(runTab, "Cowork", StringComparison.OrdinalIgnoreCase)
? BuildCoworkSystemPrompt()
: null;
var codeSystem = string.Equals(runTab, "Code", StringComparison.OrdinalIgnoreCase)
? BuildCodeSystemPrompt()
: null;
var (resolvedService, _) = _llm.GetCurrentModelInfo();
var executionMode = _chatEngine.ResolveExecutionMode(
runTab,
_settings.Settings.Llm.Streaming,
resolvedService,
coworkSystem,
codeSystem);
var promptStack = _chatEngine.BuildPromptStack(
conv.SystemCommand,
null,
executionMode.TaskSystemPrompt);
var response = await _llm.SendAsync(sendMessages, _streamCts.Token);
List<ChatMessage> sendMessages;
lock (_convLock)
sendMessages = _chatEngine.PrepareTurn(conv, promptStack, null, null).Messages;
var response = executionMode.UseAgentLoop
? await RunAgentLoopAsync(runTab, runTab, conv, sendMessages, _streamCts.Token)
: await _llm.SendAsync(sendMessages, _streamCts.Token);
assistantContent = response;
StopAiIconPulse();
_cachedStreamContent = response;
@@ -11025,14 +11042,17 @@ public partial class ChatWindow : Window
BtnSend.Visibility = Visibility.Visible;
_streamCts?.Dispose();
_streamCts = null;
_streamRunTab = null;
SetStatusIdle();
}
assistantContent = string.IsNullOrWhiteSpace(assistantContent) ? "(빈 응답)" : assistantContent;
assistantContent = BuildAssistantFallbackContent(conv, runTab, assistantContent);
if (runTab is "Cowork" or "Code")
conv.ShowExecutionHistory = false;
lock (_convLock)
{
var session = ChatSession;
_chatEngine.CommitAssistantMessage(session, conv, _activeTab, assistantContent, _storage);
_chatEngine.CommitAssistantMessage(session, conv, runTab, assistantContent, _storage);
_currentConversation = session?.CurrentConversation ?? conv;
conv = _currentConversation!;
}