diff --git a/README.md b/README.md index 548bb66..096c331 100644 --- a/README.md +++ b/README.md @@ -752,6 +752,7 @@ ow + toggle 시각 언어로 통일했습니다. - 이번엔 실행 이벤트가 들어올 때 창 코드가 즉시 많이 만지던 UI 갱신도 배치형으로 묶었습니다. [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)에 `_agentUiEventTimer`, `ScheduleAgentUiEvent(...)`, `FlushPendingAgentUiEvent()`를 추가해서, 상태바/스티키 진행률/플랜 뷰어/파일 탐색기 자동 새로고침/제안 토스트/자동 프리뷰 반영이 가장 최근 이벤트 기준으로 90ms 단위로만 화면에 반영되게 했습니다. - `OnAgentEvent(...)`는 이제 실행 이벤트 자체를 대화 모델과 앱 상태에 먼저 반영하고, 화면 갱신은 배치된 UI 이벤트 flush가 담당합니다. 이 조정으로 Cowork/Code 실행 중 빠른 이벤트 연속 구간에서 상태바와 진행률, 파일 미리보기 쪽이 따로따로 즉시 흔들리던 체감을 더 줄이는 방향으로 정리했습니다. - 대기열 다음 작업 시작도 입력창 UI에 의존하지 않게 바꿨습니다. [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 `SendMessageAsync(...)`는 이제 선택적으로 직접 텍스트를 받을 수 있고, `StartNextQueuedDraftIfAny(...)`는 더 이상 `InputBox.Text`를 바꿔 포커스를 흔든 뒤 전송하지 않고 `SendMessageAsync(next.Text)`로 바로 실행합니다. 이걸로 Cowork/Code 자동 이어달리기가 입력창 상태를 덜 건드리게 됐습니다. +- 실패 후 재시도도 같은 방향으로 정리했습니다. [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 `RetryLastUserMessageFromConversation()`는 이제 입력창에 마지막 요청을 다시 밀어 넣지 않고, 유휴 상태면 `SendMessageAsync(lastUserMessage)`로 바로 다시 실행하고, 이미 작업 중이면 같은 요청을 곧바로 대기열에 적재합니다. 재시도 동작도 입력창 포커스와 높이를 흔들지 않게 만든 조정입니다. - 검증: `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:31 (KST) @@ -765,6 +766,7 @@ ow + toggle 시각 언어로 통일했습니다. - 업데이트: 2026-04-05 13:20 (KST) - 업데이트: 2026-04-05 13:29 (KST) - 업데이트: 2026-04-05 13:37 (KST) +- 업데이트: 2026-04-05 13:44 (KST) --- diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 6d3bad8..348e9a8 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -4525,3 +4525,6 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎. - 업데이트: 2026-04-05 13:37 (KST) - 남아 있던 큰 UI 결합점인 “대기열 실행이 입력창을 거쳐 시작되는 구조”도 줄였습니다. [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 `SendMessageAsync(...)`는 이제 직접 텍스트 인자를 받을 수 있고, `StartNextQueuedDraftIfAny(...)`는 `InputBox.Text = next.Text` / `Focus()` / `UpdateInputBoxHeight()`를 거치지 않고 `SendMessageAsync(next.Text)`를 바로 호출합니다. - 이 변경으로 대기열 기반 Cowork/Code 후속 작업은 입력창 상태와 포커스를 덜 흔들고, 실행 축 자체가 입력 UI보다 엔진/세션 흐름에 더 가까워졌습니다. 현재 남은 마감 작업은 완료 카드와 일부 에러 재시도 표시처럼 아직 창 코드에 남아 있는 소수의 직접 UI 후처리를 더 줄이는 단계입니다. +- 업데이트: 2026-04-05 13:44 (KST) +- `RetryLastUserMessageFromConversation()`도 입력창 의존을 제거했습니다. 마지막 사용자 요청을 재시도할 때 더 이상 `InputBox.Text`를 바꾸지 않고, 유휴 상태면 `SendMessageAsync(lastUserMessage)`로 바로 실행하며, 이미 작업 중이면 `ChatSession.EnqueueDraft(..., \"now\", ..., \"direct\")`로 곧바로 대기열에 올립니다. +- 이 조정으로 실패 후 재시도 역시 입력창 포커스/높이/슬래시 칩 상태와 분리되었고, Cowork/Code의 재시도 흐름이 세션/대기열 중심으로 더 정리됐습니다. diff --git a/src/AxCopilot/Views/ChatWindow.xaml.cs b/src/AxCopilot/Views/ChatWindow.xaml.cs index 4cadbfb..1e8c519 100644 --- a/src/AxCopilot/Views/ChatWindow.xaml.cs +++ b/src/AxCopilot/Views/ChatWindow.xaml.cs @@ -21178,13 +21178,26 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi private void RetryLastUserMessageFromConversation() { var lastUserMessage = GetLastUserMessageFromConversation(); - if (string.IsNullOrWhiteSpace(lastUserMessage) || InputBox == null) + if (string.IsNullOrWhiteSpace(lastUserMessage)) return; - InputBox.Text = lastUserMessage; - InputBox.CaretIndex = InputBox.Text.Length; - InputBox.Focus(); - QueueComposerDraft(priority: "now", explicitKind: "direct", startImmediatelyWhenIdle: true); + if (_isStreaming) + { + lock (_convLock) + { + var session = ChatSession; + if (session != null) + _currentConversation = session.EnqueueDraft(_activeTab, lastUserMessage, "now", _storage, "direct") != null + ? session.CurrentConversation + : _currentConversation; + } + + RefreshDraftQueueUi(); + ShowToast("현재 작업 뒤에 같은 요청을 다시 실행하도록 대기열에 추가했습니다."); + return; + } + + _ = SendMessageAsync(lastUserMessage); } private void FocusCurrentConversation()