- OnAgentEvent가 실행 이벤트마다 본문 전체를 즉시 다시 그리지 않도록 execution history 전용 배치 렌더 타이머를 추가함 - Cowork/Code 실행 중 RenderMessages 호출을 120ms 단위로 묶어 본문 번쩍임과 잦은 로그 재배치를 줄임 - 검증: 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:
@@ -742,12 +742,14 @@ ow + toggle 시각 언어로 통일했습니다.
|
|||||||
- 이어서 `FinalizeAssistantTurn(...)`를 엔진에 추가해, 최종 assistant 내용 정규화와 Cowork/Code 실행 로그 접힘 처리, assistant 메시지 커밋을 전송/재생성 공통으로 같은 메서드에서 처리하게 바꿨습니다. 이제 채팅 마무리 단계도 UI 코드가 아니라 엔진이 더 많이 책임집니다.
|
- 이어서 `FinalizeAssistantTurn(...)`를 엔진에 추가해, 최종 assistant 내용 정규화와 Cowork/Code 실행 로그 접힘 처리, assistant 메시지 커밋을 전송/재생성 공통으로 같은 메서드에서 처리하게 바꿨습니다. 이제 채팅 마무리 단계도 UI 코드가 아니라 엔진이 더 많이 책임집니다.
|
||||||
- 이번엔 [AxAgentExecutionEngine.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Services/Agent/AxAgentExecutionEngine.cs)에 `ExecutePreparedAsync(...)`를 추가해서, 준비된 실행이 `AgentLoop`를 탈지 일반 LLM 호출을 탈지 결정하는 분기까지 엔진이 맡도록 옮겼습니다. [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 일반 전송과 재생성은 이제 둘 다 `ExecutePreparedAsync(...)`만 호출합니다.
|
- 이번엔 [AxAgentExecutionEngine.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Services/Agent/AxAgentExecutionEngine.cs)에 `ExecutePreparedAsync(...)`를 추가해서, 준비된 실행이 `AgentLoop`를 탈지 일반 LLM 호출을 탈지 결정하는 분기까지 엔진이 맡도록 옮겼습니다. [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 일반 전송과 재생성은 이제 둘 다 `ExecutePreparedAsync(...)`만 호출합니다.
|
||||||
- 이어서 [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 실행 후처리도 `ResetStreamingUiState()`, `FinalizeConversationTurn()`, `FinalizeQueuedDraft()`로 묶었습니다. 전송과 재생성이 같은 정리 경로를 공유하게 해서, 응답 완료 뒤 상태 복구와 대화 저장, 대기열 완료/실패 처리 흐름도 더 한 축으로 정리했습니다.
|
- 이어서 [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 실행 후처리도 `ResetStreamingUiState()`, `FinalizeConversationTurn()`, `FinalizeQueuedDraft()`로 묶었습니다. 전송과 재생성이 같은 정리 경로를 공유하게 해서, 응답 완료 뒤 상태 복구와 대화 저장, 대기열 완료/실패 처리 흐름도 더 한 축으로 정리했습니다.
|
||||||
|
- 이번엔 `OnAgentEvent(...)`의 본문 재렌더를 배치형으로 바꿨습니다. [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)에 `DispatcherTimer` 기반 `ScheduleExecutionHistoryRender()`를 추가해서, Cowork/Code 실행 중 이벤트가 연속으로 들어와도 `RenderMessages()`가 매 이벤트마다 바로 돌지 않고 짧게 묶여 한 번씩만 반영됩니다.
|
||||||
- 검증: `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-05 12:24 (KST)
|
- 업데이트: 2026-04-05 12:24 (KST)
|
||||||
- 업데이트: 2026-04-05 12:31 (KST)
|
- 업데이트: 2026-04-05 12:31 (KST)
|
||||||
- 업데이트: 2026-04-05 12:36 (KST)
|
- 업데이트: 2026-04-05 12:36 (KST)
|
||||||
- 업데이트: 2026-04-05 12:41 (KST)
|
- 업데이트: 2026-04-05 12:41 (KST)
|
||||||
- 업데이트: 2026-04-05 12:47 (KST)
|
- 업데이트: 2026-04-05 12:47 (KST)
|
||||||
|
- 업데이트: 2026-04-05 12:53 (KST)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -4501,4 +4501,7 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
|
|||||||
- 업데이트: 2026-04-05 12:47 (KST)
|
- 업데이트: 2026-04-05 12:47 (KST)
|
||||||
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)에 `ResetStreamingUiState()`, `FinalizeConversationTurn()`, `FinalizeQueuedDraft()`를 추가해, 전송과 재생성에 흩어져 있던 실행 후 UI/상태 정리 로직을 공통화했습니다.
|
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)에 `ResetStreamingUiState()`, `FinalizeConversationTurn()`, `FinalizeQueuedDraft()`를 추가해, 전송과 재생성에 흩어져 있던 실행 후 UI/상태 정리 로직을 공통화했습니다.
|
||||||
- 이 변경으로 응답 완료 후의 `타이머 중지`, `버튼 상태 복원`, `스트림 필드 정리`, `대화 저장`, `대화 목록 갱신`, `대기열 완료/실패 반영`, `다음 큐 작업 시작` 경로가 전송과 재생성에서 같은 helper를 공유하게 됐습니다. 현재 AX Agent 채팅 엔진 공통화는 준비/실행 선택/최종 커밋/후처리까지 대부분 한 축으로 모이는 단계까지 왔습니다.
|
- 이 변경으로 응답 완료 후의 `타이머 중지`, `버튼 상태 복원`, `스트림 필드 정리`, `대화 저장`, `대화 목록 갱신`, `대기열 완료/실패 반영`, `다음 큐 작업 시작` 경로가 전송과 재생성에서 같은 helper를 공유하게 됐습니다. 현재 AX Agent 채팅 엔진 공통화는 준비/실행 선택/최종 커밋/후처리까지 대부분 한 축으로 모이는 단계까지 왔습니다.
|
||||||
|
- 업데이트: 2026-04-05 12:53 (KST)
|
||||||
|
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)에 `_executionHistoryRenderTimer`와 `ScheduleExecutionHistoryRender()`를 추가해, `OnAgentEvent(...)`가 실행 이벤트마다 즉시 `RenderMessages()`를 호출하지 않도록 바꿨습니다.
|
||||||
|
- 이제 `ShowExecutionHistory`가 켜진 Cowork/Code 대화에서도 실행 이벤트가 짧은 간격으로 몰릴 때는 120ms 단위로 재렌더를 묶어서 한 번만 반영합니다. 이건 실행 중 본문이 번쩍이거나 로그 잔상이 자주 갱신되는 체감을 줄이기 위한 배치 렌더 단계입니다.
|
||||||
- 검증: `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
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ public partial class ChatWindow : Window
|
|||||||
private readonly DispatcherTimer _gitRefreshTimer;
|
private readonly DispatcherTimer _gitRefreshTimer;
|
||||||
private readonly DispatcherTimer _conversationSearchTimer;
|
private readonly DispatcherTimer _conversationSearchTimer;
|
||||||
private readonly DispatcherTimer _inputUiRefreshTimer;
|
private readonly DispatcherTimer _inputUiRefreshTimer;
|
||||||
|
private readonly DispatcherTimer _executionHistoryRenderTimer;
|
||||||
private CancellationTokenSource? _gitStatusRefreshCts;
|
private CancellationTokenSource? _gitStatusRefreshCts;
|
||||||
private int _displayedLength; // 현재 화면에 표시된 글자 수
|
private int _displayedLength; // 현재 화면에 표시된 글자 수
|
||||||
private ResourceDictionary? _agentThemeDictionary;
|
private ResourceDictionary? _agentThemeDictionary;
|
||||||
@@ -116,6 +117,7 @@ public partial class ChatWindow : Window
|
|||||||
private int _sessionPostCompactionResponseCount;
|
private int _sessionPostCompactionResponseCount;
|
||||||
private int _sessionPostCompactionPromptTokens;
|
private int _sessionPostCompactionPromptTokens;
|
||||||
private int _sessionPostCompactionCompletionTokens;
|
private int _sessionPostCompactionCompletionTokens;
|
||||||
|
private bool _pendingExecutionHistoryAutoScroll;
|
||||||
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)
|
||||||
@@ -233,6 +235,15 @@ public partial class ChatWindow : Window
|
|||||||
RefreshContextUsageVisual();
|
RefreshContextUsageVisual();
|
||||||
RefreshDraftQueueUi();
|
RefreshDraftQueueUi();
|
||||||
};
|
};
|
||||||
|
_executionHistoryRenderTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(120) };
|
||||||
|
_executionHistoryRenderTimer.Tick += (_, _) =>
|
||||||
|
{
|
||||||
|
_executionHistoryRenderTimer.Stop();
|
||||||
|
RenderMessages(preserveViewport: true);
|
||||||
|
if (_pendingExecutionHistoryAutoScroll)
|
||||||
|
AutoScrollIfNeeded();
|
||||||
|
_pendingExecutionHistoryAutoScroll = false;
|
||||||
|
};
|
||||||
|
|
||||||
KeyDown += ChatWindow_KeyDown;
|
KeyDown += ChatWindow_KeyDown;
|
||||||
UpdateConversationFailureFilterUi();
|
UpdateConversationFailureFilterUi();
|
||||||
@@ -8536,6 +8547,8 @@ public partial class ChatWindow : Window
|
|||||||
_cursorTimer.Stop();
|
_cursorTimer.Stop();
|
||||||
_elapsedTimer.Stop();
|
_elapsedTimer.Stop();
|
||||||
_typingTimer.Stop();
|
_typingTimer.Stop();
|
||||||
|
_executionHistoryRenderTimer.Stop();
|
||||||
|
_pendingExecutionHistoryAutoScroll = false;
|
||||||
HideStickyProgress();
|
HideStickyProgress();
|
||||||
StopRainbowGlow();
|
StopRainbowGlow();
|
||||||
_activeStreamText = null;
|
_activeStreamText = null;
|
||||||
@@ -8592,6 +8605,13 @@ public partial class ChatWindow : Window
|
|||||||
_ = Dispatcher.BeginInvoke(new Action(() => StartNextQueuedDraftIfAny()), DispatcherPriority.Background);
|
_ = Dispatcher.BeginInvoke(new Action(() => StartNextQueuedDraftIfAny()), DispatcherPriority.Background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ScheduleExecutionHistoryRender(bool autoScroll = true)
|
||||||
|
{
|
||||||
|
_pendingExecutionHistoryAutoScroll |= autoScroll;
|
||||||
|
_executionHistoryRenderTimer.Stop();
|
||||||
|
_executionHistoryRenderTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
// ─── 코워크 에이전트 지원 ────────────────────────────────────────────
|
// ─── 코워크 에이전트 지원 ────────────────────────────────────────────
|
||||||
|
|
||||||
private string BuildCoworkSystemPrompt()
|
private string BuildCoworkSystemPrompt()
|
||||||
@@ -8995,8 +9015,7 @@ public partial class ChatWindow : Window
|
|||||||
AppendConversationExecutionEvent(evt, eventTab);
|
AppendConversationExecutionEvent(evt, eventTab);
|
||||||
if (shouldShowExecutionHistory
|
if (shouldShowExecutionHistory
|
||||||
&& string.Equals(eventTab, _activeTab, StringComparison.OrdinalIgnoreCase))
|
&& string.Equals(eventTab, _activeTab, StringComparison.OrdinalIgnoreCase))
|
||||||
RenderMessages(preserveViewport: true);
|
ScheduleExecutionHistoryRender(autoScroll: true);
|
||||||
AutoScrollIfNeeded();
|
|
||||||
|
|
||||||
// 하단 상태바 업데이트
|
// 하단 상태바 업데이트
|
||||||
UpdateStatusBar(evt);
|
UpdateStatusBar(evt);
|
||||||
|
|||||||
Reference in New Issue
Block a user