AX Agent background conversation ??? UI ?? ??

?? ??? ?? ??? ?? ?? ?? ??? ??? ?? ?? ?? ???? ??? ????.

ChatStreamingUiPolicy? ?? ??? ??? ActiveConversation ???? ???, ChatWindow? ??? ??? ?? ??? ????.

AgentProgressHintTimer? StreamMetricsLabel? background conversation ????? ??? UI? ?? ??? ??? ????, ?? ???? README/DEVELOPMENT ??? ????.

??: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify_background_conversation_live_ui\\ -p:IntermediateOutputPath=obj\\verify_background_conversation_live_ui\\
??: dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter "ChatStreamingUiPolicyTests|AppStateServiceTests" -p:OutputPath=bin\\verify_background_conversation_live_ui_tests\\ -p:IntermediateOutputPath=obj\\verify_background_conversation_live_ui_tests\\
This commit is contained in:
2026-04-15 22:37:13 +09:00
parent 82e58bde57
commit e2553a10ae
7 changed files with 52 additions and 7 deletions

View File

@@ -27,8 +27,8 @@ public class ChatStreamingUiPolicyTests
[Theory]
[InlineData(nameof(StreamingGuideVisibility.Hidden), false)]
[InlineData(nameof(StreamingGuideVisibility.ActiveConversation), true)]
[InlineData(nameof(StreamingGuideVisibility.BackgroundConversation), true)]
public void ShouldShowTopLevelGuide_ShouldKeepGuideVisibleForBackgroundConversation(
[InlineData(nameof(StreamingGuideVisibility.BackgroundConversation), false)]
public void ShouldShowTopLevelGuide_ShouldOnlyShowGuideForVisibleStreamingConversation(
string visibilityName,
bool expected)
{

View File

@@ -24,7 +24,7 @@ internal static class ChatStreamingUiPolicy
}
internal static bool ShouldShowTopLevelGuide(StreamingGuideVisibility visibility)
=> visibility != StreamingGuideVisibility.Hidden;
=> visibility == StreamingGuideVisibility.ActiveConversation;
internal static bool ShouldRenderConversationBoundContent(StreamingGuideVisibility visibility)
=> visibility == StreamingGuideVisibility.ActiveConversation;

View File

@@ -319,6 +319,19 @@ public partial class ChatWindow
return;
}
var guideVisibility = GetGuideVisibilityForActiveTab();
if (!ChatStreamingUiPolicy.ShouldShowTopLevelGuide(guideVisibility))
{
RemoveAgentLiveCard(animated: false);
HideStreamingStatusBar();
HideStickyProgress();
UpdateLiveAgentProgressHint(null, runTab: _activeTab);
UpdateStreamMetricsLabel(
(int)Math.Max(0, _tabCumulativeInputTokens.GetValueOrDefault(_activeTab)),
(int)Math.Max(0, _tabCumulativeOutputTokens.GetValueOrDefault(_activeTab)));
return;
}
// _streamingTabs.Contains(_activeTab)가 위에서 이미 검증됨 — _streamRunTab은 다른 탭 시작 시 덮어써질 수 있으므로 _activeTab 사용
var runTab = _activeTab;
if (!string.Equals(runTab, "Cowork", StringComparison.OrdinalIgnoreCase)

View File

@@ -236,12 +236,18 @@ public partial class ChatWindow
{
if (StreamMetricsLabel == null) return;
if (!_isStreaming)
if (!_isStreaming || !ChatStreamingUiPolicy.ShouldShowTopLevelGuide(GetGuideVisibilityForActiveTab()))
{
StreamMetricsLabel.Visibility = Visibility.Collapsed;
return;
}
if (inputTokens == 0 && outputTokens == 0)
{
inputTokens = (int)Math.Max(0, _tabCumulativeInputTokens.GetValueOrDefault(_activeTab));
outputTokens = (int)Math.Max(0, _tabCumulativeOutputTokens.GetValueOrDefault(_activeTab));
}
StreamMetricsLabel.Visibility = Visibility.Visible;
var elapsedText = "0s";

View File

@@ -1684,9 +1684,7 @@ public partial class ChatWindow : Window
private void RefreshStreamingControlsForActiveTab()
{
var isOwningTab = _streamingTabs.Contains(_activeTab);
var guideVisibility = ChatStreamingUiPolicy.ResolveGuideVisibility(
isOwningTab,
isOwningTab && IsStreamingConversationVisible(_activeTab));
var guideVisibility = GetGuideVisibilityForActiveTab();
var shouldShowTopLevelGuide = ChatStreamingUiPolicy.ShouldShowTopLevelGuide(guideVisibility);
// 실행 중에도 Send 버튼 표시 — 메시지가 큐에 추가됨
@@ -1724,6 +1722,10 @@ public partial class ChatWindow : Window
if (pendingUiEvent != null)
UpdateAgentLiveCardV2(pendingUiEvent);
}
UpdateStreamMetricsLabel(
(int)Math.Max(0, _tabCumulativeInputTokens.GetValueOrDefault(_activeTab)),
(int)Math.Max(0, _tabCumulativeOutputTokens.GetValueOrDefault(_activeTab)));
}
private void TrackStreamingConversation(string tab, ChatConversation conversation)
@@ -1759,6 +1761,14 @@ public partial class ChatWindow : Window
}
}
private StreamingGuideVisibility GetGuideVisibilityForActiveTab()
{
var isOwningTab = _streamingTabs.Contains(_activeTab);
return ChatStreamingUiPolicy.ResolveGuideVisibility(
isOwningTab,
isOwningTab && IsStreamingConversationVisible(_activeTab));
}
private void ClearStreamingConversation(string tab, ChatConversation? expectedConversation = null)
{
var normalizedTab = NormalizeTabName(tab);