From 675bdc95951d847557899dc8d43ef2bb0f5bae12 Mon Sep 17 00:00:00 2001 From: lacvet Date: Wed, 15 Apr 2026 15:30:31 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EB=A3=A8=ED=94=842=20?= =?UTF-8?q?=EC=9D=B4=ED=9B=84=20=EC=82=AC=EB=9D=BC=EC=A7=84=20=EC=BD=94?= =?UTF-8?q?=EC=9B=8C=ED=81=AC/=EC=BD=94=EB=93=9C=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20=EC=B9=B4=EB=93=9C=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 메인 루프2 리팩터링 이후 StartLiveAgentProgressHints가 하단 상태 힌트만 시작하고 채팅창 바로 위 V2 라이브 카드를 다시 만들지 않아 Cowork/Code 실행 중 라이브 카드가 보이지 않던 회귀를 수정했다. - StartLiveAgentProgressHints에서 Cowork/Code 실행 시작 시 ShowAgentLiveCard(runTab)를 다시 호출하도록 복구 - Chat 같은 비대상 탭은 시작 시 기존 라이브 카드를 즉시 정리하도록 보강 - IsAgentLiveCardEligibleTab 헬퍼를 추가해 라이브 카드 대상 탭 판정을 한곳으로 고정 - ChatWindowSlashPolicyTests에 라이브 카드 대상 탭 회귀 테스트 추가 - README.md, docs/DEVELOPMENT.md에 2026-04-15 15:27 (KST) 기준 작업 이력과 검증 결과 반영 검증: - dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify_live_card_restore\\ -p:IntermediateOutputPath=obj\\verify_live_card_restore\\ (경고 0 / 오류 0) - dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter ChatWindowSlashPolicyTests -p:OutputPath=bin\\verify_live_card_restore_tests\\ -p:IntermediateOutputPath=obj\\verify_live_card_restore_tests\\ (통과 49) --- README.md | 7 +++++++ docs/DEVELOPMENT.md | 20 +++++++++++++++++++ .../Views/ChatWindowSlashPolicyTests.cs | 13 ++++++++++++ .../ChatWindow.LiveProgressPresentation.cs | 4 ++++ src/AxCopilot/Views/ChatWindow.xaml.cs | 5 +++-- 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a034007..5636a75 100644 --- a/README.md +++ b/README.md @@ -2101,3 +2101,10 @@ MIT License - 새 [StreamingToolExecutionCoordinatorTests.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot.Tests/Services/StreamingToolExecutionCoordinatorTests.cs)는 느린 첫 응답일 때 waiting heartbeat가 발생하는지와 빠른 응답에서는 불필요한 wait 문구를 남기지 않는지를 회귀 검증합니다. - 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify_llm_wait_diag\\ -p:IntermediateOutputPath=obj\\verify_llm_wait_diag\\` 경고 0 / 오류 0 - 검증: `dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter "StreamingToolExecutionCoordinatorTests|AgentLoopLlmRequestPreparationServiceTests|AgentLoopIterationPreparationServiceTests" -p:OutputPath=bin\\verify_llm_wait_diag_tests\\ -p:IntermediateOutputPath=obj\\verify_llm_wait_diag_tests\\` 통과 6 + +업데이트: 2026-04-15 15:27 (KST) +- 메인 루프2 이후 Cowork/Code 채팅창 바로 위의 라이브 카드가 사라진 회귀를 복구했습니다. [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 `StartLiveAgentProgressHints()`가 이제 Cowork/Code 실행 시작 시 [ChatWindow.LiveProgressPresentation.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.LiveProgressPresentation.cs)의 라이브 카드 생성 경로를 다시 호출합니다. +- 탭 판정은 `IsAgentLiveCardEligibleTab(...)` 헬퍼로 분리해 `Cowork`, `Code`만 라이브 카드 대상이 되도록 고정했고, Chat 같은 비대상 탭은 시작 시 기존 카드를 즉시 정리하도록 맞췄습니다. +- 테스트: [ChatWindowSlashPolicyTests.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot.Tests/Views/ChatWindowSlashPolicyTests.cs)에 라이브 카드 대상 탭 회귀 검증 추가 +- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify_live_card_restore\\ -p:IntermediateOutputPath=obj\\verify_live_card_restore\\` 경고 0 / 오류 0 +- 검증: `dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter "ChatWindowSlashPolicyTests" -p:OutputPath=bin\\verify_live_card_restore_tests\\ -p:IntermediateOutputPath=obj\\verify_live_card_restore_tests\\` 통과 49 diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index d18b05e..a5dc64e 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -1397,3 +1397,23 @@ UI ?붿옄???€洹쒕え 由ы뙥?좊쭅 ???꾪뿕 ?묒뾽 ??湲곕줉???덉쟾 ### 검증 - `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify_llm_wait_diag\\ -p:IntermediateOutputPath=obj\\verify_llm_wait_diag\\` 경고 0 / 오류 0 - `dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter "StreamingToolExecutionCoordinatorTests|AgentLoopLlmRequestPreparationServiceTests|AgentLoopIterationPreparationServiceTests" -p:OutputPath=bin\\verify_llm_wait_diag_tests\\ -p:IntermediateOutputPath=obj\\verify_llm_wait_diag_tests\\` 통과 6 + +업데이트: 2026-04-15 15:27 (KST) + +### Cowork/Code 라이브 카드 시작 경로 복구 +- `src/AxCopilot/Views/ChatWindow.xaml.cs` + - `StartLiveAgentProgressHints()`가 Cowork/Code 실행 시작 시 `ShowAgentLiveCard(runTab)`를 다시 호출하도록 복구했습니다. + - 메인 루프2 이후 상태 힌트/하단 바만 시작되고, 채팅창 바로 위 라이브 카드 컨테이너를 만들지 않던 회귀를 수정한 것입니다. + - 비대상 탭(Chat 등) 실행 시작 시에는 `RemoveAgentLiveCard(animated: false)`로 기존 라이브 카드를 즉시 정리해 탭 전환 뒤 잔상이 남지 않게 맞췄습니다. + +- `src/AxCopilot/Views/ChatWindow.LiveProgressPresentation.cs` + - `IsAgentLiveCardEligibleTab(string? runTab)` 헬퍼를 추가해 라이브 카드 대상 탭을 `Cowork`, `Code`로 고정했습니다. + - 시작 경로와 회귀 테스트가 같은 판정식을 사용하도록 묶어 탭 조건이 다시 어긋나지 않게 했습니다. + +### 테스트 +- `src/AxCopilot.Tests/Views/ChatWindowSlashPolicyTests.cs` + - `IsAgentLiveCardEligibleTab_ShouldMatchExpectedTabs()` 추가 + +### 검증 +- `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify_live_card_restore\\ -p:IntermediateOutputPath=obj\\verify_live_card_restore\\` 경고 0 / 오류 0 +- `dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter "ChatWindowSlashPolicyTests" -p:OutputPath=bin\\verify_live_card_restore_tests\\ -p:IntermediateOutputPath=obj\\verify_live_card_restore_tests\\` 통과 49 diff --git a/src/AxCopilot.Tests/Views/ChatWindowSlashPolicyTests.cs b/src/AxCopilot.Tests/Views/ChatWindowSlashPolicyTests.cs index 0579406..f0eb46f 100644 --- a/src/AxCopilot.Tests/Views/ChatWindowSlashPolicyTests.cs +++ b/src/AxCopilot.Tests/Views/ChatWindowSlashPolicyTests.cs @@ -185,4 +185,17 @@ public class ChatWindowSlashPolicyTests success.Should().BeFalse(); error.Should().Contain("토큰"); } + [Theory] + [InlineData("Code", true)] + [InlineData("Cowork", true)] + [InlineData("Chat", false)] + [InlineData("", false)] + public void IsAgentLiveCardEligibleTab_ShouldMatchExpectedTabs(string runTab, bool expected) + { + var method = typeof(ChatWindow).GetMethod("IsAgentLiveCardEligibleTab", BindingFlags.NonPublic | BindingFlags.Static); + method.Should().NotBeNull(); + + var result = method!.Invoke(null, new object?[] { runTab }); + result.Should().Be(expected); + } } diff --git a/src/AxCopilot/Views/ChatWindow.LiveProgressPresentation.cs b/src/AxCopilot/Views/ChatWindow.LiveProgressPresentation.cs index 94d41dc..3c64cd4 100644 --- a/src/AxCopilot/Views/ChatWindow.LiveProgressPresentation.cs +++ b/src/AxCopilot/Views/ChatWindow.LiveProgressPresentation.cs @@ -10,6 +10,10 @@ namespace AxCopilot.Views; public partial class ChatWindow { + private static bool IsAgentLiveCardEligibleTab(string? runTab) + => string.Equals(runTab, "Cowork", StringComparison.OrdinalIgnoreCase) + || string.Equals(runTab, "Code", StringComparison.OrdinalIgnoreCase); + private void ShowAgentLiveCard(string runTab) { if (MessageList == null) return; diff --git a/src/AxCopilot/Views/ChatWindow.xaml.cs b/src/AxCopilot/Views/ChatWindow.xaml.cs index 87a3f59..8cdbdee 100644 --- a/src/AxCopilot/Views/ChatWindow.xaml.cs +++ b/src/AxCopilot/Views/ChatWindow.xaml.cs @@ -6728,15 +6728,16 @@ public partial class ChatWindow : Window _lastAgentProgressEventAt = DateTime.UtcNow; _currentRunProgressSteps.Clear(); var runTab = string.IsNullOrWhiteSpace(_streamRunTab) ? _activeTab : _streamRunTab!; - if (string.Equals(runTab, "Cowork", StringComparison.OrdinalIgnoreCase) - || string.Equals(runTab, "Code", StringComparison.OrdinalIgnoreCase)) + if (IsAgentLiveCardEligibleTab(runTab)) { + ShowAgentLiveCard(runTab); var initialStatus = AgentStatusNarrativeCatalog.BuildInitial(runTab); UpdateLiveAgentProgressHint(initialStatus.Message, "agent_wait"); ShowStreamingStatusBar(initialStatus.Message, detail: initialStatus.Detail); } else { + RemoveAgentLiveCard(animated: false); UpdateLiveAgentProgressHint(null); ShowStreamingStatusBar("생각하는 중..."); }