Compare commits
2 Commits
f8baea24f5
...
fbaaf19391
| Author | SHA1 | Date | |
|---|---|---|---|
| fbaaf19391 | |||
| a686d822e7 |
@@ -1448,3 +1448,10 @@ MIT License
|
|||||||
|
|
||||||
- 업데이트: 2026-04-07 02:11 (KST)
|
- 업데이트: 2026-04-07 02:11 (KST)
|
||||||
- AX Agent 내부 설정 공통 탭의 Gemini/Claude API 키 입력 필드를 PasswordBox에서 TextBox로 교체해, 오버레이 동기화 중에도 입력이 끊기거나 튕기지 않도록 수정했습니다.
|
- AX Agent 내부 설정 공통 탭의 Gemini/Claude API 키 입력 필드를 PasswordBox에서 TextBox로 교체해, 오버레이 동기화 중에도 입력이 끊기거나 튕기지 않도록 수정했습니다.
|
||||||
|
- 업데이트: 2026-04-07 02:45 (KST)
|
||||||
|
- Cowork/Code 진행 카드의 경과 시간 계산을 보정했습니다. 스트리밍 시작 시각이 준비되기 전에 진행 힌트가 먼저 그려질 때 `수천만 시간`처럼 비정상값이 표시되던 문제를 막고, 6시간을 넘는 비현실적인 경과 시간은 자동 무시하도록 정리했습니다.
|
||||||
|
- AX Agent 입력창 글로우를 런처와 같은 리듬의 무지개 글로우로 다시 맞췄습니다. 글로우 외곽선 두께와 블러를 부드럽게 조정하고, 라이브 진행 카드도 테마 AccentColor 기반의 은은한 톤을 써서 주황색 고정 느낌을 줄였습니다.
|
||||||
|
- 일반 설정에 있던 `런처 무지개 글로우`, `선택 아이템 글로우`, `채팅 입력창 무지개 글로우`를 AX Agent 내부 설정으로 이동해, 이제 내부 설정에서 바로 런처/입력창 글로우를 함께 조정할 수 있습니다.
|
||||||
|
- 업데이트: 2026-04-07 02:56 (KST)
|
||||||
|
- AX Agent 내부 설정 개발자 탭의 `워크플로우 시각화`가 숨은 개발자 모드 의존 때문에 실제로 창을 띄우지 않던 문제를 수정했습니다. 이제 토글을 켜면 즉시 워크플로우 분석기 창이 열리고, 끄면 창이 숨겨집니다.
|
||||||
|
- 일반 설정에만 남아 있던 `문서 미리보기 자동 표시` 옵션을 AX Agent 내부 설정 공통 탭에도 복원해, Cowork/Code에서 프리뷰 자동 열기 정책을 내부 설정에서 바로 바꿀 수 있게 했습니다.
|
||||||
|
|||||||
@@ -5287,3 +5287,27 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
|
|||||||
- Document update: 2026-04-07 02:23 (KST) - Reconnected the AX Agent direct-chat execution path to the existing SSE/streaming transport in `LlmService`. Chat replies no longer wait for the final full string before rendering; when streaming is enabled they now advance through the existing streaming container and typing-timer path.
|
- Document update: 2026-04-07 02:23 (KST) - Reconnected the AX Agent direct-chat execution path to the existing SSE/streaming transport in `LlmService`. Chat replies no longer wait for the final full string before rendering; when streaming is enabled they now advance through the existing streaming container and typing-timer path.
|
||||||
- Document update: 2026-04-07 02:23 (KST) - Updated `AxAgentExecutionEngine.ResolveExecutionMode()` so non-agent chat can opt into streaming transport, and wired `ChatWindow.ExecutePreparedTurnAsync()` to consume `LlmService.StreamAsync(...)` for direct conversations while keeping Cowork/Code on the agent-loop progress-feed path.
|
- Document update: 2026-04-07 02:23 (KST) - Updated `AxAgentExecutionEngine.ResolveExecutionMode()` so non-agent chat can opt into streaming transport, and wired `ChatWindow.ExecutePreparedTurnAsync()` to consume `LlmService.StreamAsync(...)` for direct conversations while keeping Cowork/Code on the agent-loop progress-feed path.
|
||||||
- Document update: 2026-04-07 02:31 (KST) - Added a typed final-response preview for Cowork/Code agent-loop completions. Those tabs still use progress-feed execution during the loop, but once a final assistant answer is available it now passes through the same streaming container/typing presentation before the final transcript message is committed.
|
- Document update: 2026-04-07 02:31 (KST) - Added a typed final-response preview for Cowork/Code agent-loop completions. Those tabs still use progress-feed execution during the loop, but once a final assistant answer is available it now passes through the same streaming container/typing presentation before the final transcript message is committed.
|
||||||
|
|
||||||
|
## 2026-04-07 02:45 (KST)
|
||||||
|
|
||||||
|
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)
|
||||||
|
- Cowork/Code 실행 시작 시 `_streamStartTime`을 라이브 진행 힌트보다 먼저 설정하도록 순서를 조정했다.
|
||||||
|
- 유효한 시작 시각이 없을 때는 진행 힌트 경과 시간을 계산하지 않도록 막아 `수천만 시간` 같은 비정상 표시를 방지했다.
|
||||||
|
- 내부 설정 저장 시 `EnableChatRainbowGlow`, `Launcher.EnableRainbowGlow`, `Launcher.EnableSelectionGlow`도 함께 반영되도록 연결했다.
|
||||||
|
- [ChatWindow.AgentEventRendering.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs)
|
||||||
|
- 진행 카드 메타에 쓰는 경과 시간을 6시간 상한으로 정규화해 비정상값을 자동 무시하도록 했다.
|
||||||
|
- 라이브 대기 카드와 진행 줄 배경을 고정 주황색 대신 테마 AccentColor 기반 반투명 톤으로 교체했다.
|
||||||
|
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml)
|
||||||
|
- 입력창 글로우 외곽선의 두께와 블러를 완화해 런처 글로우와 더 비슷한 질감으로 조정했다.
|
||||||
|
- AX Agent 내부 설정 공통 탭에 `글로우 효과` 섹션을 추가해 런처 무지개 글로우, 런처 선택 글로우, 채팅 입력창 글로우를 내부 설정에서 바로 조정할 수 있게 했다.
|
||||||
|
- [SettingsWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/SettingsWindow.xaml)
|
||||||
|
- 일반 설정 테마 섹션에 있던 런처/채팅 글로우 토글 3종을 제거해 AX Agent 내부 설정으로 UI를 일원화했다.
|
||||||
|
|
||||||
|
## 2026-04-07 02:56 (KST)
|
||||||
|
|
||||||
|
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)
|
||||||
|
- `워크플로우 시각화`가 `DevMode`에 묶여 토글을 켜도 실제 분석기 창이 열리지 않던 의존을 제거했다.
|
||||||
|
- 설정 저장 후 `SyncWorkflowVisualizerWindow()`를 호출해, 토글을 켜면 분석기 창이 바로 열리고 끄면 즉시 숨겨지도록 연결했다.
|
||||||
|
- 내부 설정 공통 탭의 자동 프리뷰 콤보 값을 `Llm.AutoPreview`와 동기화하고, 변경 시 바로 저장되도록 `CmbOverlayAutoPreview_SelectionChanged`를 추가했다.
|
||||||
|
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml)
|
||||||
|
- AX Agent 내부 설정 공통 탭에 `문서 미리보기` 콤보를 추가해 `자동 표시 / 수동 / 비활성화`를 내부 설정에서 직접 제어할 수 있게 했다.
|
||||||
|
|||||||
@@ -10,6 +10,22 @@ namespace AxCopilot.Views;
|
|||||||
|
|
||||||
public partial class ChatWindow
|
public partial class ChatWindow
|
||||||
{
|
{
|
||||||
|
private static Color ResolveLiveProgressAccentColor(Brush accentBrush)
|
||||||
|
{
|
||||||
|
return accentBrush is SolidColorBrush solid
|
||||||
|
? solid.Color
|
||||||
|
: Color.FromRgb(0x59, 0xA5, 0xF5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long NormalizeProgressElapsedMs(long elapsedMs)
|
||||||
|
{
|
||||||
|
if (elapsedMs <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var maxReasonableElapsed = (long)TimeSpan.FromHours(6).TotalMilliseconds;
|
||||||
|
return elapsedMs > maxReasonableElapsed ? 0 : elapsedMs;
|
||||||
|
}
|
||||||
|
|
||||||
private Border CreateCompactEventPill(
|
private Border CreateCompactEventPill(
|
||||||
string summary,
|
string summary,
|
||||||
Brush primaryText,
|
Brush primaryText,
|
||||||
@@ -20,13 +36,14 @@ public partial class ChatWindow
|
|||||||
string? metaText = null,
|
string? metaText = null,
|
||||||
bool liveWaitingStyle = false)
|
bool liveWaitingStyle = false)
|
||||||
{
|
{
|
||||||
|
var liveAccentColor = ResolveLiveProgressAccentColor(accentBrush);
|
||||||
return new Border
|
return new Border
|
||||||
{
|
{
|
||||||
Background = liveWaitingStyle
|
Background = liveWaitingStyle
|
||||||
? new SolidColorBrush(Color.FromArgb(0x20, 0xF5, 0x73, 0x16))
|
? new SolidColorBrush(Color.FromArgb(0x16, liveAccentColor.R, liveAccentColor.G, liveAccentColor.B))
|
||||||
: hintBg,
|
: hintBg,
|
||||||
BorderBrush = liveWaitingStyle
|
BorderBrush = liveWaitingStyle
|
||||||
? new SolidColorBrush(Color.FromArgb(0x4D, 0xF5, 0x73, 0x16))
|
? new SolidColorBrush(Color.FromArgb(0x46, liveAccentColor.R, liveAccentColor.G, liveAccentColor.B))
|
||||||
: borderBrush,
|
: borderBrush,
|
||||||
BorderThickness = new Thickness(1),
|
BorderThickness = new Thickness(1),
|
||||||
CornerRadius = new CornerRadius(10),
|
CornerRadius = new CornerRadius(10),
|
||||||
@@ -267,9 +284,10 @@ public partial class ChatWindow
|
|||||||
{
|
{
|
||||||
var parts = new List<string>();
|
var parts = new List<string>();
|
||||||
|
|
||||||
if (evt.ElapsedMs > 0)
|
var normalizedElapsedMs = NormalizeProgressElapsedMs(evt.ElapsedMs);
|
||||||
|
if (normalizedElapsedMs > 0)
|
||||||
{
|
{
|
||||||
var elapsed = TimeSpan.FromMilliseconds(evt.ElapsedMs);
|
var elapsed = TimeSpan.FromMilliseconds(normalizedElapsedMs);
|
||||||
if (elapsed.TotalHours >= 1)
|
if (elapsed.TotalHours >= 1)
|
||||||
parts.Add($"{(int)elapsed.TotalHours}h {elapsed.Minutes}m");
|
parts.Add($"{(int)elapsed.TotalHours}h {elapsed.Minutes}m");
|
||||||
else if (elapsed.TotalMinutes >= 1)
|
else if (elapsed.TotalMinutes >= 1)
|
||||||
@@ -324,11 +342,12 @@ public partial class ChatWindow
|
|||||||
bool liveWaitingStyle,
|
bool liveWaitingStyle,
|
||||||
out Border pulseMarker)
|
out Border pulseMarker)
|
||||||
{
|
{
|
||||||
|
var liveAccentColor = ResolveLiveProgressAccentColor(accentBrush);
|
||||||
var cardBackground = liveWaitingStyle
|
var cardBackground = liveWaitingStyle
|
||||||
? new SolidColorBrush(Color.FromArgb(0x20, 0xF5, 0x73, 0x16))
|
? new SolidColorBrush(Color.FromArgb(0x16, liveAccentColor.R, liveAccentColor.G, liveAccentColor.B))
|
||||||
: hintBg;
|
: hintBg;
|
||||||
var cardBorder = liveWaitingStyle
|
var cardBorder = liveWaitingStyle
|
||||||
? new SolidColorBrush(Color.FromArgb(0x4D, 0xF5, 0x73, 0x16))
|
? new SolidColorBrush(Color.FromArgb(0x46, liveAccentColor.R, liveAccentColor.G, liveAccentColor.B))
|
||||||
: borderBrush;
|
: borderBrush;
|
||||||
|
|
||||||
pulseMarker = new Border
|
pulseMarker = new Border
|
||||||
@@ -389,9 +408,10 @@ public partial class ChatWindow
|
|||||||
{
|
{
|
||||||
var parts = new List<string>();
|
var parts = new List<string>();
|
||||||
|
|
||||||
if (evt.ElapsedMs > 0)
|
var normalizedElapsedMs = NormalizeProgressElapsedMs(evt.ElapsedMs);
|
||||||
|
if (normalizedElapsedMs > 0)
|
||||||
{
|
{
|
||||||
var elapsed = TimeSpan.FromMilliseconds(evt.ElapsedMs);
|
var elapsed = TimeSpan.FromMilliseconds(normalizedElapsedMs);
|
||||||
if (elapsed.TotalHours >= 1)
|
if (elapsed.TotalHours >= 1)
|
||||||
parts.Add($"{(int)elapsed.TotalHours}h {elapsed.Minutes}m");
|
parts.Add($"{(int)elapsed.TotalHours}h {elapsed.Minutes}m");
|
||||||
else if (elapsed.TotalMinutes >= 1)
|
else if (elapsed.TotalMinutes >= 1)
|
||||||
@@ -418,11 +438,12 @@ public partial class ChatWindow
|
|||||||
bool liveWaitingStyle,
|
bool liveWaitingStyle,
|
||||||
out Border pulseMarker)
|
out Border pulseMarker)
|
||||||
{
|
{
|
||||||
|
var liveAccentColor = ResolveLiveProgressAccentColor(accentBrush);
|
||||||
var cardBackground = liveWaitingStyle
|
var cardBackground = liveWaitingStyle
|
||||||
? new SolidColorBrush(Color.FromArgb(0x20, 0xF5, 0x73, 0x16))
|
? new SolidColorBrush(Color.FromArgb(0x16, liveAccentColor.R, liveAccentColor.G, liveAccentColor.B))
|
||||||
: Brushes.Transparent;
|
: Brushes.Transparent;
|
||||||
var cardBorder = liveWaitingStyle
|
var cardBorder = liveWaitingStyle
|
||||||
? new SolidColorBrush(Color.FromArgb(0x4D, 0xF5, 0x73, 0x16))
|
? new SolidColorBrush(Color.FromArgb(0x46, liveAccentColor.R, liveAccentColor.G, liveAccentColor.B))
|
||||||
: Brushes.Transparent;
|
: Brushes.Transparent;
|
||||||
|
|
||||||
pulseMarker = new Border
|
pulseMarker = new Border
|
||||||
@@ -1003,11 +1024,12 @@ public partial class ChatWindow
|
|||||||
Grid.SetColumn(headerLeft, 0);
|
Grid.SetColumn(headerLeft, 0);
|
||||||
|
|
||||||
var headerRight = new StackPanel { Orientation = Orientation.Horizontal };
|
var headerRight = new StackPanel { Orientation = Orientation.Horizontal };
|
||||||
if (logLevel != "simple" && evt.ElapsedMs > 0)
|
var normalizedElapsedMs = NormalizeProgressElapsedMs(evt.ElapsedMs);
|
||||||
|
if (logLevel != "simple" && normalizedElapsedMs > 0)
|
||||||
{
|
{
|
||||||
headerRight.Children.Add(new TextBlock
|
headerRight.Children.Add(new TextBlock
|
||||||
{
|
{
|
||||||
Text = evt.ElapsedMs < 1000 ? $"{evt.ElapsedMs}ms" : $"{evt.ElapsedMs / 1000.0:F1}s",
|
Text = normalizedElapsedMs < 1000 ? $"{normalizedElapsedMs}ms" : $"{normalizedElapsedMs / 1000.0:F1}s",
|
||||||
FontSize = 8.5,
|
FontSize = 8.5,
|
||||||
Foreground = secondaryText,
|
Foreground = secondaryText,
|
||||||
VerticalAlignment = VerticalAlignment.Center,
|
VerticalAlignment = VerticalAlignment.Center,
|
||||||
|
|||||||
@@ -1917,7 +1917,7 @@
|
|||||||
Visibility="Collapsed"
|
Visibility="Collapsed"
|
||||||
Margin="0,0,0,6"/>
|
Margin="0,0,0,6"/>
|
||||||
<Border x:Name="InputGlowBorder" CornerRadius="18" Opacity="0"
|
<Border x:Name="InputGlowBorder" CornerRadius="18" Opacity="0"
|
||||||
Margin="-1" IsHitTestVisible="False">
|
Margin="-2" IsHitTestVisible="False">
|
||||||
<Border.BorderBrush>
|
<Border.BorderBrush>
|
||||||
<LinearGradientBrush x:Name="RainbowBrush" StartPoint="0,0" EndPoint="1,1">
|
<LinearGradientBrush x:Name="RainbowBrush" StartPoint="0,0" EndPoint="1,1">
|
||||||
<GradientStop Color="#FF6B6B" Offset="0.0"/>
|
<GradientStop Color="#FF6B6B" Offset="0.0"/>
|
||||||
@@ -1930,10 +1930,10 @@
|
|||||||
</LinearGradientBrush>
|
</LinearGradientBrush>
|
||||||
</Border.BorderBrush>
|
</Border.BorderBrush>
|
||||||
<Border.BorderThickness>
|
<Border.BorderThickness>
|
||||||
<Thickness>1.5</Thickness>
|
<Thickness>1.15</Thickness>
|
||||||
</Border.BorderThickness>
|
</Border.BorderThickness>
|
||||||
<Border.Effect>
|
<Border.Effect>
|
||||||
<BlurEffect Radius="2"/>
|
<BlurEffect Radius="6"/>
|
||||||
</Border.Effect>
|
</Border.Effect>
|
||||||
</Border>
|
</Border>
|
||||||
<!-- 실제 입력 영역 -->
|
<!-- 실제 입력 영역 -->
|
||||||
@@ -3507,6 +3507,31 @@
|
|||||||
Style="{StaticResource OverlayComboBox}"
|
Style="{StaticResource OverlayComboBox}"
|
||||||
SelectionChanged="CmbOverlayDefaultMood_SelectionChanged"/>
|
SelectionChanged="CmbOverlayDefaultMood_SelectionChanged"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid x:Name="OverlayAutoPreviewRow" Margin="0,0,0,12">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock Text="문서 미리보기"
|
||||||
|
FontSize="12.5"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="{DynamicResource PrimaryText}"/>
|
||||||
|
<TextBlock Text="파일 생성 시 오른쪽 프리뷰 패널을 자동으로 열지 정합니다."
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
FontSize="11"
|
||||||
|
Foreground="{DynamicResource SecondaryText}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<ComboBox x:Name="CmbOverlayAutoPreview"
|
||||||
|
Grid.Column="1"
|
||||||
|
MinWidth="160"
|
||||||
|
Style="{StaticResource OverlayComboBox}"
|
||||||
|
SelectionChanged="CmbOverlayAutoPreview_SelectionChanged">
|
||||||
|
<ComboBoxItem Content="자동 표시" Tag="auto"/>
|
||||||
|
<ComboBoxItem Content="수동" Tag="manual"/>
|
||||||
|
<ComboBoxItem Content="비활성화" Tag="off"/>
|
||||||
|
</ComboBox>
|
||||||
|
</Grid>
|
||||||
<Grid x:Name="OverlayPdfExportPathRow" Margin="0,0,0,12">
|
<Grid x:Name="OverlayPdfExportPathRow" Margin="0,0,0,12">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
@@ -3688,6 +3713,99 @@
|
|||||||
</ComboBox>
|
</ComboBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
<Border x:Name="OverlaySectionGlowEffects"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderBrush="{DynamicResource BorderColor}"
|
||||||
|
BorderThickness="0,1,0,0"
|
||||||
|
CornerRadius="0"
|
||||||
|
Padding="0,12,0,0"
|
||||||
|
Margin="0,0,0,12">
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock Text="글로우 효과"
|
||||||
|
FontSize="13"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="{DynamicResource PrimaryText}"/>
|
||||||
|
<TextBlock Text="런처와 AX Agent의 글로우 연출을 여기서 조정합니다."
|
||||||
|
Margin="0,4,0,10"
|
||||||
|
FontSize="11"
|
||||||
|
Foreground="{DynamicResource SecondaryText}"/>
|
||||||
|
<Border Style="{StaticResource OverlayAdvancedToggleRowStyle}">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Margin="0,0,16,0">
|
||||||
|
<TextBlock Text="런처 무지개 글로우"
|
||||||
|
FontSize="12.5"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="{DynamicResource PrimaryText}"/>
|
||||||
|
<TextBlock Text="AX Commander 테두리에 무지개 글로우를 표시합니다."
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
FontSize="11.5"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Foreground="{DynamicResource SecondaryText}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<CheckBox x:Name="ChkOverlayEnableLauncherRainbowGlow"
|
||||||
|
Grid.Column="1"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToggleSwitch}"
|
||||||
|
Checked="ChkOverlayFeatureToggle_Changed"
|
||||||
|
Unchecked="ChkOverlayFeatureToggle_Changed"/>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
<Border Style="{StaticResource OverlayAdvancedToggleRowStyle}" Margin="0,8,0,0">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Margin="0,0,16,0">
|
||||||
|
<TextBlock Text="런처 선택 글로우"
|
||||||
|
FontSize="12.5"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="{DynamicResource PrimaryText}"/>
|
||||||
|
<TextBlock Text="선택된 런처 항목에 은은한 글로우를 표시합니다."
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
FontSize="11.5"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Foreground="{DynamicResource SecondaryText}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<CheckBox x:Name="ChkOverlayEnableSelectionGlow"
|
||||||
|
Grid.Column="1"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToggleSwitch}"
|
||||||
|
Checked="ChkOverlayFeatureToggle_Changed"
|
||||||
|
Unchecked="ChkOverlayFeatureToggle_Changed"/>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
<Border Style="{StaticResource OverlayAdvancedToggleRowStyle}" Margin="0,8,0,0">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Margin="0,0,16,0">
|
||||||
|
<TextBlock Text="채팅 입력창 글로우"
|
||||||
|
FontSize="12.5"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="{DynamicResource PrimaryText}"/>
|
||||||
|
<TextBlock Text="메시지 전송 중 입력창에 런처와 같은 무지개 글로우를 표시합니다."
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
FontSize="11.5"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Foreground="{DynamicResource SecondaryText}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<CheckBox x:Name="ChkOverlayEnableChatRainbowGlow"
|
||||||
|
Grid.Column="1"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToggleSwitch}"
|
||||||
|
Checked="ChkOverlayFeatureToggle_Changed"
|
||||||
|
Unchecked="ChkOverlayFeatureToggle_Changed"/>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
<Border x:Name="OverlayToggleImageInput" Style="{StaticResource OverlayAdvancedToggleRowStyle}">
|
<Border x:Name="OverlayToggleImageInput" Style="{StaticResource OverlayAdvancedToggleRowStyle}">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
|||||||
@@ -5302,6 +5302,7 @@ public partial class ChatWindow : Window
|
|||||||
ForceScrollToEnd(); // 사용자 메시지 전송 시 강제 하단 이동
|
ForceScrollToEnd(); // 사용자 메시지 전송 시 강제 하단 이동
|
||||||
PlayRainbowGlow(); // 무지개 글로우 애니메이션
|
PlayRainbowGlow(); // 무지개 글로우 애니메이션
|
||||||
|
|
||||||
|
_streamStartTime = DateTime.UtcNow;
|
||||||
_isStreaming = true;
|
_isStreaming = true;
|
||||||
_streamRunTab = runTab;
|
_streamRunTab = runTab;
|
||||||
StartLiveAgentProgressHints();
|
StartLiveAgentProgressHints();
|
||||||
@@ -5318,7 +5319,6 @@ public partial class ChatWindow : Window
|
|||||||
_displayedLength = 0;
|
_displayedLength = 0;
|
||||||
_cursorVisible = true;
|
_cursorVisible = true;
|
||||||
_aiIconPulseStopped = false;
|
_aiIconPulseStopped = false;
|
||||||
_streamStartTime = DateTime.UtcNow;
|
|
||||||
_elapsedTimer.Start();
|
_elapsedTimer.Start();
|
||||||
SetStatus("응답 생성 중...", spinning: true);
|
SetStatus("응답 생성 중...", spinning: true);
|
||||||
|
|
||||||
@@ -6229,7 +6229,7 @@ public partial class ChatWindow : Window
|
|||||||
private void OpenWorkflowAnalyzerIfEnabled()
|
private void OpenWorkflowAnalyzerIfEnabled()
|
||||||
{
|
{
|
||||||
var llm = _settings.Settings.Llm;
|
var llm = _settings.Settings.Llm;
|
||||||
if (!llm.DevMode || !llm.WorkflowVisualizer) return;
|
if (!llm.WorkflowVisualizer) return;
|
||||||
|
|
||||||
if (_analyzerWindow == null)
|
if (_analyzerWindow == null)
|
||||||
{
|
{
|
||||||
@@ -6266,10 +6266,23 @@ public partial class ChatWindow : Window
|
|||||||
private void UpdateAnalyzerButtonVisibility()
|
private void UpdateAnalyzerButtonVisibility()
|
||||||
{
|
{
|
||||||
var llm = _settings.Settings.Llm;
|
var llm = _settings.Settings.Llm;
|
||||||
BtnShowAnalyzer.Visibility = (llm.DevMode && llm.WorkflowVisualizer)
|
BtnShowAnalyzer.Visibility = llm.WorkflowVisualizer
|
||||||
? Visibility.Visible : Visibility.Collapsed;
|
? Visibility.Visible : Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SyncWorkflowVisualizerWindow()
|
||||||
|
{
|
||||||
|
UpdateAnalyzerButtonVisibility();
|
||||||
|
if (_settings.Settings.Llm.WorkflowVisualizer)
|
||||||
|
{
|
||||||
|
OpenWorkflowAnalyzerIfEnabled();
|
||||||
|
}
|
||||||
|
else if (_analyzerWindow != null && _analyzerWindow.IsVisible)
|
||||||
|
{
|
||||||
|
_analyzerWindow.Hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>워크플로우 분석기 창을 수동으로 열거나 포커스합니다 (하단 바 버튼).</summary>
|
/// <summary>워크플로우 분석기 창을 수동으로 열거나 포커스합니다 (하단 바 버튼).</summary>
|
||||||
private void BtnShowAnalyzer_Click(object sender, MouseButtonEventArgs e)
|
private void BtnShowAnalyzer_Click(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -6415,7 +6428,8 @@ public partial class ChatWindow : Window
|
|||||||
var normalizedSummary = string.IsNullOrWhiteSpace(summary) ? null : summary.Trim();
|
var normalizedSummary = string.IsNullOrWhiteSpace(summary) ? null : summary.Trim();
|
||||||
var currentSummary = _liveAgentProgressHint?.Summary;
|
var currentSummary = _liveAgentProgressHint?.Summary;
|
||||||
var currentToolName = _liveAgentProgressHint?.ToolName ?? "";
|
var currentToolName = _liveAgentProgressHint?.ToolName ?? "";
|
||||||
var elapsedMs = _isStreaming
|
var hasValidStreamStart = _streamStartTime.Year >= 2000 && _streamStartTime <= DateTime.UtcNow.AddSeconds(1);
|
||||||
|
var elapsedMs = _isStreaming && hasValidStreamStart
|
||||||
? Math.Max(0L, (long)(DateTime.UtcNow - _streamStartTime.ToUniversalTime()).TotalMilliseconds)
|
? Math.Max(0L, (long)(DateTime.UtcNow - _streamStartTime.ToUniversalTime()).TotalMilliseconds)
|
||||||
: 0L;
|
: 0L;
|
||||||
var inputTokens = Math.Max(0, _agentCumulativeInputTokens);
|
var inputTokens = Math.Max(0, _agentCumulativeInputTokens);
|
||||||
@@ -8769,22 +8783,18 @@ public partial class ChatWindow : Window
|
|||||||
_rainbowTimer?.Stop();
|
_rainbowTimer?.Stop();
|
||||||
_rainbowStartTime = DateTime.UtcNow;
|
_rainbowStartTime = DateTime.UtcNow;
|
||||||
|
|
||||||
// 페이드인 (빠르게)
|
InputGlowBorder.Effect = new System.Windows.Media.Effects.BlurEffect { Radius = 6 };
|
||||||
InputGlowBorder.BeginAnimation(UIElement.OpacityProperty,
|
InputGlowBorder.BeginAnimation(UIElement.OpacityProperty,
|
||||||
new System.Windows.Media.Animation.DoubleAnimation(0, 0.9, TimeSpan.FromMilliseconds(150)));
|
new System.Windows.Media.Animation.DoubleAnimation(0, 0.62, TimeSpan.FromMilliseconds(180)));
|
||||||
|
|
||||||
// 그라데이션 회전 타이머 (~60fps) — 스트리밍 종료까지 지속
|
_rainbowTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(40) };
|
||||||
_rainbowTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(16) };
|
|
||||||
_rainbowTimer.Tick += (_, _) =>
|
_rainbowTimer.Tick += (_, _) =>
|
||||||
{
|
{
|
||||||
var elapsed = (DateTime.UtcNow - _rainbowStartTime).TotalMilliseconds;
|
var elapsed = (DateTime.UtcNow - _rainbowStartTime).TotalMilliseconds;
|
||||||
|
var shift = (elapsed / 2000.0) % 1.0;
|
||||||
// 그라데이션 오프셋 회전
|
|
||||||
var shift = (elapsed / 1500.0) % 1.0; // 1.5초에 1바퀴 (느리게)
|
|
||||||
var brush = InputGlowBorder.BorderBrush as LinearGradientBrush;
|
var brush = InputGlowBorder.BorderBrush as LinearGradientBrush;
|
||||||
if (brush == null) return;
|
if (brush == null) return;
|
||||||
|
|
||||||
// 시작/끝점 회전 (원형 이동)
|
|
||||||
var angle = shift * Math.PI * 2;
|
var angle = shift * Math.PI * 2;
|
||||||
brush.StartPoint = new Point(0.5 + 0.5 * Math.Cos(angle), 0.5 + 0.5 * Math.Sin(angle));
|
brush.StartPoint = new Point(0.5 + 0.5 * Math.Cos(angle), 0.5 + 0.5 * Math.Sin(angle));
|
||||||
brush.EndPoint = new Point(0.5 - 0.5 * Math.Cos(angle), 0.5 - 0.5 * Math.Sin(angle));
|
brush.EndPoint = new Point(0.5 - 0.5 * Math.Cos(angle), 0.5 - 0.5 * Math.Sin(angle));
|
||||||
@@ -10278,6 +10288,9 @@ public partial class ChatWindow : Window
|
|||||||
llm.WorkflowVisualizer = ChkOverlayWorkflowVisualizer?.IsChecked == true;
|
llm.WorkflowVisualizer = ChkOverlayWorkflowVisualizer?.IsChecked == true;
|
||||||
llm.ShowTotalCallStats = ChkOverlayShowTotalCallStats?.IsChecked == true;
|
llm.ShowTotalCallStats = ChkOverlayShowTotalCallStats?.IsChecked == true;
|
||||||
llm.EnableAuditLog = ChkOverlayEnableAuditLog?.IsChecked == true;
|
llm.EnableAuditLog = ChkOverlayEnableAuditLog?.IsChecked == true;
|
||||||
|
llm.EnableChatRainbowGlow = ChkOverlayEnableChatRainbowGlow?.IsChecked == true;
|
||||||
|
_settings.Settings.Launcher.EnableRainbowGlow = ChkOverlayEnableLauncherRainbowGlow?.IsChecked == true;
|
||||||
|
_settings.Settings.Launcher.EnableSelectionGlow = ChkOverlayEnableSelectionGlow?.IsChecked == true;
|
||||||
|
|
||||||
CommitOverlayEndpointInput(normalizeOnInvalid: true);
|
CommitOverlayEndpointInput(normalizeOnInvalid: true);
|
||||||
CommitOverlayApiKeyInput();
|
CommitOverlayApiKeyInput();
|
||||||
@@ -10314,6 +10327,7 @@ public partial class ChatWindow : Window
|
|||||||
ApplyAgentThemeResources();
|
ApplyAgentThemeResources();
|
||||||
UpdatePermissionUI();
|
UpdatePermissionUI();
|
||||||
UpdateDataUsageUI();
|
UpdateDataUsageUI();
|
||||||
|
SyncWorkflowVisualizerWindow();
|
||||||
SaveConversationSettings();
|
SaveConversationSettings();
|
||||||
RefreshInlineSettingsPanel();
|
RefreshInlineSettingsPanel();
|
||||||
UpdateModelLabel();
|
UpdateModelLabel();
|
||||||
@@ -10482,6 +10496,12 @@ public partial class ChatWindow : Window
|
|||||||
ChkOverlayShowTotalCallStats.IsChecked = llm.ShowTotalCallStats;
|
ChkOverlayShowTotalCallStats.IsChecked = llm.ShowTotalCallStats;
|
||||||
if (ChkOverlayEnableAuditLog != null)
|
if (ChkOverlayEnableAuditLog != null)
|
||||||
ChkOverlayEnableAuditLog.IsChecked = llm.EnableAuditLog;
|
ChkOverlayEnableAuditLog.IsChecked = llm.EnableAuditLog;
|
||||||
|
if (ChkOverlayEnableChatRainbowGlow != null)
|
||||||
|
ChkOverlayEnableChatRainbowGlow.IsChecked = llm.EnableChatRainbowGlow;
|
||||||
|
if (ChkOverlayEnableLauncherRainbowGlow != null)
|
||||||
|
ChkOverlayEnableLauncherRainbowGlow.IsChecked = _settings.Settings.Launcher.EnableRainbowGlow;
|
||||||
|
if (ChkOverlayEnableSelectionGlow != null)
|
||||||
|
ChkOverlayEnableSelectionGlow.IsChecked = _settings.Settings.Launcher.EnableSelectionGlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefreshOverlayThemeCards();
|
RefreshOverlayThemeCards();
|
||||||
@@ -11197,6 +11217,8 @@ public partial class ChatWindow : Window
|
|||||||
OverlayDefaultOutputFormatRow.Visibility = showCowork ? Visibility.Visible : Visibility.Collapsed;
|
OverlayDefaultOutputFormatRow.Visibility = showCowork ? Visibility.Visible : Visibility.Collapsed;
|
||||||
if (OverlayDefaultMoodRow != null)
|
if (OverlayDefaultMoodRow != null)
|
||||||
OverlayDefaultMoodRow.Visibility = showCowork ? Visibility.Visible : Visibility.Collapsed;
|
OverlayDefaultMoodRow.Visibility = showCowork ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
if (OverlayAutoPreviewRow != null)
|
||||||
|
OverlayAutoPreviewRow.Visibility = showShared ? Visibility.Visible : Visibility.Collapsed;
|
||||||
if (OverlayPdfExportPathRow != null)
|
if (OverlayPdfExportPathRow != null)
|
||||||
OverlayPdfExportPathRow.Visibility = showChat ? Visibility.Visible : Visibility.Collapsed;
|
OverlayPdfExportPathRow.Visibility = showChat ? Visibility.Visible : Visibility.Collapsed;
|
||||||
if (OverlayToggleImageInput != null)
|
if (OverlayToggleImageInput != null)
|
||||||
@@ -12577,6 +12599,7 @@ public partial class ChatWindow : Window
|
|||||||
SelectComboTag(CmbOverlayFastMode, llm.FreeTierMode ? "on" : "off");
|
SelectComboTag(CmbOverlayFastMode, llm.FreeTierMode ? "on" : "off");
|
||||||
SelectComboTag(CmbOverlayDefaultOutputFormat, llm.DefaultOutputFormat ?? "auto");
|
SelectComboTag(CmbOverlayDefaultOutputFormat, llm.DefaultOutputFormat ?? "auto");
|
||||||
SelectComboTag(CmbOverlayDefaultMood, _selectedMood ?? llm.DefaultMood ?? "modern");
|
SelectComboTag(CmbOverlayDefaultMood, _selectedMood ?? llm.DefaultMood ?? "modern");
|
||||||
|
SelectComboTag(CmbOverlayAutoPreview, llm.AutoPreview ?? "off");
|
||||||
SelectComboTag(CmbOverlayAgentLogLevel, llm.AgentLogLevel ?? "simple");
|
SelectComboTag(CmbOverlayAgentLogLevel, llm.AgentLogLevel ?? "simple");
|
||||||
UpdateDataUsageUI();
|
UpdateDataUsageUI();
|
||||||
}
|
}
|
||||||
@@ -13084,6 +13107,15 @@ public partial class ChatWindow : Window
|
|||||||
PersistOverlaySettingsState(refreshOverlayDeferredInputs: false);
|
PersistOverlaySettingsState(refreshOverlayDeferredInputs: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CmbOverlayAutoPreview_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_isOverlaySettingsSyncing || CmbOverlayAutoPreview.SelectedItem is not ComboBoxItem selected || selected.Tag is not string tag)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_settings.Settings.Llm.AutoPreview = tag;
|
||||||
|
PersistOverlaySettingsState(refreshOverlayDeferredInputs: false);
|
||||||
|
}
|
||||||
|
|
||||||
private void CmbOverlayOperationMode_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void CmbOverlayOperationMode_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (_isOverlaySettingsSyncing || CmbOverlayOperationMode.SelectedItem is not ComboBoxItem selected || selected.Tag is not string tag)
|
if (_isOverlaySettingsSyncing || CmbOverlayOperationMode.SelectedItem is not ComboBoxItem selected || selected.Tag is not string tag)
|
||||||
|
|||||||
@@ -1195,52 +1195,6 @@
|
|||||||
<!-- 테마 선택 패널 -->
|
<!-- 테마 선택 패널 -->
|
||||||
<ScrollViewer x:Name="ThemeSelectPanel" Grid.Row="2" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
<ScrollViewer x:Name="ThemeSelectPanel" Grid.Row="2" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<!-- ── 시각 효과 ── -->
|
|
||||||
<TextBlock Text="시각 효과" Style="{StaticResource SectionHeader}"/>
|
|
||||||
<Border Style="{StaticResource SettingsRow}">
|
|
||||||
<Grid>
|
|
||||||
<StackPanel HorizontalAlignment="Left" Margin="0,0,60,0">
|
|
||||||
<StackPanel Orientation="Horizontal">
|
|
||||||
<TextBlock Style="{StaticResource RowLabel}" Text="런처 무지개 글로우"/>
|
|
||||||
<Border Width="16" Height="16" CornerRadius="8" Background="{DynamicResource ItemHoverBackground}" Margin="6,0,0,0" Cursor="Help" VerticalAlignment="Center">
|
|
||||||
<TextBlock Text="?" FontSize="10" FontWeight="Bold" Foreground="{DynamicResource AccentColor}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
||||||
<Border.ToolTip>
|
|
||||||
<ToolTip Style="{StaticResource HelpTooltipStyle}">
|
|
||||||
<TextBlock TextWrapping="Wrap" Foreground="White" FontSize="12" LineHeight="18">
|
|
||||||
AX Commander 테두리에 무지개빛 회전 애니메이션을 표시합니다.
|
|
||||||
<LineBreak/>GPU 가속을 사용하므로 저사양 PC에서는 끄는 것을 권장합니다.
|
|
||||||
</TextBlock>
|
|
||||||
</ToolTip>
|
|
||||||
</Border.ToolTip>
|
|
||||||
</Border>
|
|
||||||
</StackPanel>
|
|
||||||
<TextBlock Style="{StaticResource RowHint}" Text="AX Commander 테두리에 무지개빛 글로우 효과를 표시합니다. 저사양 PC에서는 끄는 것을 권장합니다."/>
|
|
||||||
</StackPanel>
|
|
||||||
<CheckBox Style="{StaticResource ToggleSwitch}" HorizontalAlignment="Right" VerticalAlignment="Center"
|
|
||||||
IsChecked="{Binding EnableRainbowGlow, Mode=TwoWay}"/>
|
|
||||||
</Grid>
|
|
||||||
</Border>
|
|
||||||
<Border Style="{StaticResource SettingsRow}">
|
|
||||||
<Grid>
|
|
||||||
<StackPanel HorizontalAlignment="Left" Margin="0,0,60,0">
|
|
||||||
<TextBlock Style="{StaticResource RowLabel}" Text="선택 아이템 글로우"/>
|
|
||||||
<TextBlock Style="{StaticResource RowHint}" Text="선택된 항목에 은은한 글로우를 상시 표시합니다. 테마 AccentColor를 기반으로 색상이 적용됩니다."/>
|
|
||||||
</StackPanel>
|
|
||||||
<CheckBox Style="{StaticResource ToggleSwitch}" HorizontalAlignment="Right" VerticalAlignment="Center"
|
|
||||||
IsChecked="{Binding EnableSelectionGlow, Mode=TwoWay}"/>
|
|
||||||
</Grid>
|
|
||||||
</Border>
|
|
||||||
<Border Style="{StaticResource SettingsRow}">
|
|
||||||
<Grid>
|
|
||||||
<StackPanel HorizontalAlignment="Left" Margin="0,0,60,0">
|
|
||||||
<TextBlock Style="{StaticResource RowLabel}" Text="채팅 입력창 무지개 글로우"/>
|
|
||||||
<TextBlock Style="{StaticResource RowHint}" Text="메시지 전송 시 입력창 테두리에 무지개빛 글로우 효과를 표시합니다. 저사양 PC에서는 끄는 것을 권장합니다."/>
|
|
||||||
</StackPanel>
|
|
||||||
<CheckBox Style="{StaticResource ToggleSwitch}" HorizontalAlignment="Right" VerticalAlignment="Center"
|
|
||||||
IsChecked="{Binding EnableChatRainbowGlow, Mode=TwoWay}"/>
|
|
||||||
</Grid>
|
|
||||||
</Border>
|
|
||||||
|
|
||||||
<TextBlock Text="테마 선택" Style="{StaticResource SectionHeader}"/>
|
<TextBlock Text="테마 선택" Style="{StaticResource SectionHeader}"/>
|
||||||
<Border Background="White" CornerRadius="10" Padding="14,10" Margin="0,0,0,14">
|
<Border Background="White" CornerRadius="10" Padding="14,10" Margin="0,0,0,14">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
|||||||
Reference in New Issue
Block a user