From b391dfdfb3311ca708224711aa46c975c9d4098c Mon Sep 17 00:00:00 2001 From: lacvet Date: Tue, 7 Apr 2026 09:31:57 +0900 Subject: [PATCH] =?UTF-8?q?=ED=95=98=EB=8B=A8=20=EC=95=88=EB=82=B4=20?= =?UTF-8?q?=EC=B9=B4=EB=93=9C=20=EA=B0=80=EB=A6=BC=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=EC=99=80=20=EB=9D=BC=EC=9D=B4=EB=B8=8C=20=ED=83=80=EC=9D=B4?= =?UTF-8?q?=ED=95=91=20=ED=91=9C=EC=8B=9C=EB=A5=BC=20=EB=B3=B4=EC=A0=95?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Cowork·Chat 하단 프리셋 안내 카드가 실제 결과를 가리지 않도록 대화 메시지 존재 시 자동으로 숨기도록 조정 - FooterPresentation에 남아 있던 깨진 한글 워터마크와 상태 문구를 정상 한국어로 복구 - 라이브 타이핑 속도와 최종 프리뷰 deadline을 재조정해 SSE 및 Cowork·Code 최종 응답이 한 번에 붙지 않고 더 눈에 보이게 표시되도록 보정 --- README.md | 4 ++++ docs/DEVELOPMENT.md | 6 ++++++ .../Views/ChatWindow.FooterPresentation.cs | 17 +++++++++++------ src/AxCopilot/Views/ChatWindow.xaml.cs | 9 +++++---- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a46043f..0ce0bb6 100644 --- a/README.md +++ b/README.md @@ -1469,3 +1469,7 @@ MIT License - 업데이트: 2026-04-07 09:32 (KST) - Cowork/Code 장시간 실행 뒤 마지막 응답을 라이브 프리뷰로 붙이는 단계에서 `_streamCts` 필드를 다시 읽다가 `Object reference not set to an instance of an object.`로 실패할 수 있던 경로를 수정했습니다. 이제 실행 시작 시 캡처한 지역 토큰을 끝까지 재사용하고, 최종 타이핑 프리뷰 컨테이너가 준비되지 않으면 조용히 건너뛰도록 방어 로직을 추가했습니다. - 같은 실패가 다시 생기면 원인을 더 빨리 찾을 수 있도록 AX Agent 실행 예외 전체를 앱 로그에 남기도록 보강했습니다. +- 업데이트: 2026-04-07 09:44 (KST) + - Cowork/Chat 하단의 프리셋 안내 카드가 실제 결과를 가리던 문제를 수정했습니다. 이제 대화에 사용자/assistant 메시지가 생기거나 실행 중일 때는 해당 카드가 자동으로 숨겨집니다. + - [ChatWindow.FooterPresentation.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.FooterPresentation.cs)에 남아 있던 깨진 한글 워터마크/안내 문구를 정상 한국어로 정리했습니다. + - 라이브 타이핑 속도를 조정해 SSE 및 Cowork/Code 최종 프리뷰가 한 번에 붙는 느낌을 줄이고, 더 눈에 보이게 점진적으로 출력되도록 보정했습니다. diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 946fb45..0fe8f16 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -5328,6 +5328,12 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎. - Cowork/Code 장시간 실행 뒤 최종 응답을 `ShowTypedAssistantPreviewAsync(...)`로 붙이는 단계에서 `_streamCts` 필드를 다시 읽다가 null 참조로 실패할 수 있던 경로를 수정했다. 실행 시작 시 만든 `CancellationTokenSource`의 토큰을 지역 변수로 고정해 마지막 프리뷰 단계까지 재사용하도록 변경했다. - 최종 타이핑 프리뷰 컨테이너가 정상적으로 준비되지 않은 경우 조용히 건너뛰도록 방어 로직을 추가했고, 타이핑 대기 중 취소가 들어오면 `OperationCanceledException`을 내부에서 흡수해 최종 실패로 뒤집히지 않도록 정리했다. - 에이전트 실행 중 예외 전체를 `Services.LogService.Debug(...)`에 남겨, 이후 장시간 실행 실패 원인을 앱 로그에서 바로 추적할 수 있게 했다. +- [ChatWindow.FooterPresentation.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.FooterPresentation.cs) + - Cowork/Chat 하단 프리셋 안내 카드의 문자열을 정상 한국어로 복구했다. + - 실제 사용자/assistant 메시지가 이미 있거나 스트리밍 중일 때는 프리셋 안내 카드를 자동으로 숨겨, 결과 본문을 가리지 않도록 조정했다. + - Cowork/Code 입력 워터마크와 폴더/메모리 상태 문구도 정상 한국어로 다시 정리했다. +- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) + - `TypingTimer_Tick(...)`의 글자 증가량과 최종 프리뷰 deadline을 재조정해, 스트리밍/최종 프리뷰가 한 번에 붙는 느낌 없이 더 눈에 보이는 타이핑 흐름으로 출력되도록 보정했다. - Document update: 2026-04-07 09:19 (KST) - Restored the AX Agent footer/status total token aggregate so it no longer disappears after runs return to idle. The status strip now rehydrates totals from the current conversation message token sums when live loop counters are empty. - Document update: 2026-04-07 09:19 (KST) - Corrected context-compaction popup accuracy by switching its detail copy to the last real compaction metrics (`before -> after`, automatic/manual kind, cumulative compaction count, cumulative saved tokens) instead of only the generic trigger-threshold text. - Document update: 2026-04-07 09:19 (KST) - Prevented `total_stats` loop events from being swallowed into the generic process-feed path. AX Agent now routes those events back through the dedicated total-stats presentation so transcript summaries and footer token totals stay aligned. diff --git a/src/AxCopilot/Views/ChatWindow.FooterPresentation.cs b/src/AxCopilot/Views/ChatWindow.FooterPresentation.cs index 9581e12..47308ee 100644 --- a/src/AxCopilot/Views/ChatWindow.FooterPresentation.cs +++ b/src/AxCopilot/Views/ChatWindow.FooterPresentation.cs @@ -25,8 +25,8 @@ public partial class ChatWindow ? "문서 작성, 데이터 분석, 파일 작업을 요청하세요. 필요하면 작업 폴더 파일도 함께 참고합니다." : "문서 작성, 데이터 분석, 파일 작업을 요청하세요. 작업 폴더를 선택하면 관련 파일도 함께 참고합니다.", "Code" => hasFolder - ? "코드 수정, 원인 분석, 빌드·테스트를 요청하세요. 작업 폴더 코드를 참고하고 저장소 상태도 함께 보여줍니다." - : "작업 폴더를 선택한 뒤 코드 수정, 원인 분석, 빌드·테스트를 요청하세요.", + ? "코드 수정, 원인 분석, 빌드와 테스트를 요청하세요. 작업 폴더 코드와 저장소 상태를 함께 참고합니다." + : "작업 폴더를 선택한 뒤 코드 수정, 원인 분석, 빌드와 테스트를 요청하세요.", _ => "질문, 요약, 초안 작성, 아이디어 정리를 요청하세요.", }; } @@ -49,7 +49,7 @@ public partial class ChatWindow if (string.Equals(_activeTab, "Cowork", StringComparison.OrdinalIgnoreCase)) return "선택한 작업 유형에 맞춰 문서·데이터·파일 작업 흐름으로 이어집니다."; - return "선택한 대화 주제에 맞춰 응답 방향과 초안 흐름이 정리됩니다."; + return "선택한 대화 주제에 맞춰 응답 방향과 초안 흐름을 정리합니다."; } private void UpdateFolderBar() @@ -199,7 +199,7 @@ public partial class ChatWindow { panel.Children.Add(new TextBlock { - Text = "감사 로그가 꺼져 있어 include 이력을 기록하지 않습니다.", + Text = "감사 로그가 꺼져 있어 include 이력은 기록되지 않습니다.", FontSize = 11, Foreground = secondaryText, TextWrapping = TextWrapping.Wrap, @@ -354,7 +354,13 @@ public partial class ChatWindow if (SelectedPresetGuide == null || SelectedPresetGuideTitle == null || SelectedPresetGuideDesc == null) return; - if (string.Equals(_activeTab, "Code", StringComparison.OrdinalIgnoreCase)) + conversation ??= _currentConversation; + var hasVisibleMessages = conversation?.Messages?.Any(m => + !string.IsNullOrWhiteSpace(m.Content) && + (string.Equals(m.Role, "user", StringComparison.OrdinalIgnoreCase) || + string.Equals(m.Role, "assistant", StringComparison.OrdinalIgnoreCase))) == true; + + if (string.Equals(_activeTab, "Code", StringComparison.OrdinalIgnoreCase) || hasVisibleMessages || _isStreaming) { SelectedPresetGuide.Visibility = Visibility.Collapsed; SelectedPresetGuideTitle.Text = ""; @@ -362,7 +368,6 @@ public partial class ChatWindow return; } - conversation ??= _currentConversation; var category = conversation?.Category?.Trim(); if (string.IsNullOrWhiteSpace(category)) { diff --git a/src/AxCopilot/Views/ChatWindow.xaml.cs b/src/AxCopilot/Views/ChatWindow.xaml.cs index f2614b8..a21be67 100644 --- a/src/AxCopilot/Views/ChatWindow.xaml.cs +++ b/src/AxCopilot/Views/ChatWindow.xaml.cs @@ -2372,9 +2372,10 @@ public partial class ChatWindow : Window // 버퍼에 쌓인 미표시 글자 수에 따라 속도 적응 var pending = targetLen - _displayedLength; int step; - if (pending > 200) step = Math.Min(pending / 5, 40); // 대량 버퍼: 빠르게 따라잡기 - else if (pending > 50) step = Math.Min(pending / 4, 15); // 중간 버퍼: 적당히 가속 - else step = Math.Min(3, pending); // 소량: 자연스러운 1~3자 + if (pending > 300) step = Math.Min(Math.Max(8, pending / 12), 18); // 대량 버퍼도 한 번에 다 붙지 않게 제한 + else if (pending > 120) step = Math.Min(Math.Max(5, pending / 14), 10); // 중간 버퍼는 자연스럽게 가속 + else if (pending > 24) step = Math.Min(4, pending); // 소량은 1~4자 + else step = Math.Min(2, pending); // 마무리는 더 천천히 _displayedLength += step; @@ -5750,7 +5751,7 @@ public partial class ChatWindow : Window _typingTimer.Start(); streamText.Text = _cursorVisible ? "\u258c" : " "; - var deadline = DateTime.UtcNow.AddMilliseconds(Math.Clamp(finalContent.Length * 6, 500, 1800)); + var deadline = DateTime.UtcNow.AddMilliseconds(Math.Clamp(finalContent.Length * 18, 1400, 6500)); try { while (_displayedLength < _cachedStreamContent.Length && DateTime.UtcNow < deadline && !ct.IsCancellationRequested)