AX Agent 내부 설정 서비스 전환과 테마 노출 정리\n\n- 공통 탭의 서비스 상세 패널을 주소 입력과 API 키 패널로 분리하고 Gemini/Claude에서는 주소 입력을 숨기도록 조정\n- 서비스 변경 직후 현재 서비스, 현재 모델, 라벨이 즉시 갱신되도록 내부 설정 새로고침 경로 보강\n- 테마 스타일과 테마 모드를 서비스/모델 바로 아래로 이동해 공통 탭에서 바로 보이게 재배치\n- README와 DEVELOPMENT 문서에 내부 설정 공통 탭 수정 이력 및 검증 결과 반영\n\n검증 결과\n- dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\\n- 경고 0 / 오류 0
Some checks failed
Release Gate / gate (push) Has been cancelled

This commit is contained in:
2026-04-05 16:26:15 +09:00
parent c3e1422b02
commit 29652c3ad4
4 changed files with 135 additions and 106 deletions

View File

@@ -888,6 +888,11 @@ ow + toggle 시각 언어로 통일했습니다.
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 에서는 빈 상태 제목/설명 폰트도 함께 키워 이 화면 전반의 글자 크기가 너무 작아 보이지 않게 보정했습니다.
- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\` 경고 0 / 오류 0
- 업데이트: 2026-04-05 19:02 (KST)
- AX Agent 내부 설정 공통 탭의 서비스 전환 UX를 다시 바로잡았습니다. [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 에서 서비스 상세 영역을 `주소 입력``API 키` 패널로 분리해 이름을 부여했고, `테마 스타일``테마 모드`도 서비스/모델 바로 아래에서 보이도록 공통 설정 상단으로 옮겼습니다.
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) 에서는 `RefreshOverlayServiceFieldVisibility(...)` 를 추가해 `Gemini/Claude` 선택 시 주소 입력 패널을 접고 API 키만 전체 폭으로 보이게 만들었습니다. `Ollama/vLLM` 은 기존처럼 주소와 키를 함께 보여줍니다.
- 같은 파일의 `SetOverlayService(...)` 는 저장 직후 `RefreshOverlayVisualState(true)` 를 다시 호출하도록 바꿔, 현재 서비스/현재 모델/라벨이 즉시 갱신되게 했습니다. 이제 Gemini를 눌렀는데도 `현재 서비스=Ollama`, `Ollama 서버 주소`가 남아 있는 어긋남을 줄였습니다.
- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\` 경고 0 / 오류 0
- 업데이트: 2026-04-05 19:10 (KST)
---

View File

@@ -4648,3 +4648,8 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 에서는 `EmptyStateTitle`, `EmptyStateDesc` 폰트를 키워 현재 빈 상태 화면 전반의 글자 크기도 함께 보정했습니다.
- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify\ -p:IntermediateOutputPath=obj\verify\` 경고 0 / 오류 0
- 업데이트: 2026-04-05 19:02 (KST)
- AX Agent 내부 설정 공통 탭의 서비스/테마 배치를 다시 정리했습니다. [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 에서 서비스 상세 패널을 `OverlayEndpointFieldPanel`, `OverlayApiKeyFieldPanel`로 분리하고, `테마 스타일`, `테마 모드` 블록을 서비스/모델 상세 바로 아래로 이동해 공통 탭에서 바로 보이게 조정했습니다.
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) 에 `RefreshOverlayServiceFieldVisibility(...)` 를 추가했습니다. 이 메서드는 `Gemini/Claude` 선택 시 주소 입력 패널을 접고 API 키 패널을 전체 폭으로 확장하며, `Ollama/vLLM` 은 주소+키 2열 구성을 유지합니다. `RefreshOverlayVisualState(...)` 에도 이 가시성 동기화를 추가했습니다.
- 같은 파일의 `SetOverlayService(...)` 는 설정 저장 직후 `RefreshOverlayVisualState(loadDeferredInputs: true)` 를 강제 호출하도록 바꿨습니다. 내부 설정에서 서비스 카드를 눌렀을 때 `현재 서비스`, `현재 모델`, 주소/키 라벨이 즉시 바뀌지 않던 문제를 바로잡기 위한 변경입니다.
- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify\ -p:IntermediateOutputPath=obj\verify\` 경고 0 / 오류 0
- 업데이트: 2026-04-05 19:10 (KST)

View File

@@ -2672,7 +2672,8 @@
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Margin="0,0,6,0">
<StackPanel x:Name="OverlayEndpointFieldPanel"
Margin="0,0,6,0">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="OverlayEndpointLabel"
Text="기본 서버 주소"
@@ -2711,7 +2712,9 @@
Foreground="{DynamicResource PrimaryText}"
FontSize="12"/>
</StackPanel>
<StackPanel Grid.Column="1" Margin="6,0,0,0">
<StackPanel x:Name="OverlayApiKeyFieldPanel"
Grid.Column="1"
Margin="6,0,0,0">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="OverlayApiKeyLabel"
Text="API 키"
@@ -2750,6 +2753,108 @@
FontSize="12"/>
</StackPanel>
</Grid>
<StackPanel x:Name="OverlayThemeStylePanel"
Visibility="Collapsed"
Margin="0,14,0,12">
<TextBlock Text="테마 스타일"
FontSize="12.5"
FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}"/>
<TextBlock Text="AX Agent 전용 시각 언어를 고릅니다. 채팅 본문과 설정 카드 모두 같은 스타일로 바뀝니다."
Margin="0,4,0,8"
FontSize="11"
TextWrapping="Wrap"
Foreground="{DynamicResource SecondaryText}"/>
<WrapPanel>
<Border x:Name="OverlayThemeStyleClawCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeStyleClawCard_MouseLeftButtonUp">
<TextBlock Text="Claw"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
<Border x:Name="OverlayThemeStyleCodexCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeStyleCodexCard_MouseLeftButtonUp">
<TextBlock Text="Codex"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
<Border x:Name="OverlayThemeStyleSlateCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeStyleSlateCard_MouseLeftButtonUp">
<TextBlock Text="Slate"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
</WrapPanel>
</StackPanel>
<StackPanel x:Name="OverlayThemePanel"
Visibility="Collapsed"
Margin="0,0,0,12">
<TextBlock Text="테마 모드"
FontSize="12.5"
FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}"/>
<TextBlock Text="시스템 테마를 따르거나, AX Agent만 별도로 라이트/다크 모드로 고정할 수 있습니다."
Margin="0,4,0,8"
FontSize="11"
TextWrapping="Wrap"
Foreground="{DynamicResource SecondaryText}"/>
<WrapPanel>
<Border x:Name="OverlayThemeSystemCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeSystemCard_MouseLeftButtonUp">
<TextBlock Text="System"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
<Border x:Name="OverlayThemeLightCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeLightCard_MouseLeftButtonUp">
<TextBlock Text="Light"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
<Border x:Name="OverlayThemeDarkCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeDarkCard_MouseLeftButtonUp">
<TextBlock Text="Dark"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
</WrapPanel>
</StackPanel>
</StackPanel>
</Border>
<Border x:Name="OverlaySectionQuick"
@@ -2949,108 +3054,6 @@
Checked="ChkOverlayAiEnabled_Changed"
Unchecked="ChkOverlayAiEnabled_Changed"/>
</Grid>
<StackPanel x:Name="OverlayThemeStylePanel"
Visibility="Collapsed"
Margin="0,0,0,12">
<TextBlock Text="테마 스타일"
FontSize="12.5"
FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}"/>
<TextBlock Text="AX Agent 전용 시각 언어를 고릅니다. 채팅 본문과 설정 카드 모두 같은 스타일로 바뀝니다."
Margin="0,4,0,8"
FontSize="11"
TextWrapping="Wrap"
Foreground="{DynamicResource SecondaryText}"/>
<WrapPanel>
<Border x:Name="OverlayThemeStyleClawCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeStyleClawCard_MouseLeftButtonUp">
<TextBlock Text="Claw"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
<Border x:Name="OverlayThemeStyleCodexCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeStyleCodexCard_MouseLeftButtonUp">
<TextBlock Text="Codex"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
<Border x:Name="OverlayThemeStyleSlateCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeStyleSlateCard_MouseLeftButtonUp">
<TextBlock Text="Slate"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
</WrapPanel>
</StackPanel>
<StackPanel x:Name="OverlayThemePanel"
Visibility="Collapsed"
Margin="0,0,0,12">
<TextBlock Text="테마 모드"
FontSize="12.5"
FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}"/>
<TextBlock Text="시스템 테마를 따르거나, AX Agent만 별도로 라이트/다크 모드로 고정할 수 있습니다."
Margin="0,4,0,8"
FontSize="11"
TextWrapping="Wrap"
Foreground="{DynamicResource SecondaryText}"/>
<WrapPanel>
<Border x:Name="OverlayThemeSystemCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeSystemCard_MouseLeftButtonUp">
<TextBlock Text="System"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
<Border x:Name="OverlayThemeLightCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeLightCard_MouseLeftButtonUp">
<TextBlock Text="Light"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
<Border x:Name="OverlayThemeDarkCard"
Cursor="Hand"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
Padding="10,7"
Margin="0,0,8,8"
MouseLeftButtonUp="OverlayThemeDarkCard_MouseLeftButtonUp">
<TextBlock Text="Dark"
FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
</Border>
</WrapPanel>
</StackPanel>
<Grid x:Name="OverlayDefaultOutputFormatRow" Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>

View File

@@ -14534,6 +14534,7 @@ public partial class ChatWindow : Window
RefreshOverlayModeButtons();
RefreshOverlayTokenPresetCards();
RefreshOverlayServiceFieldLabels(service);
RefreshOverlayServiceFieldVisibility(service);
BuildOverlayModelChips(service);
BuildOverlayRegisteredModelsPanel(service);
RefreshOverlayAdvancedChoiceButtons();
@@ -16402,19 +16403,33 @@ public partial class ChatWindow : Window
break;
case "gemini":
OverlayEndpointLabel.Text = "기본 서버 주소";
OverlayEndpointHint.Text = "Gemini는 기본 주소를 사용합니다. 비워두면 기본값을 사용합니다.";
OverlayEndpointHint.Text = "Gemini는 내부 기본 주소를 사용합니다.";
OverlayApiKeyLabel.Text = "Gemini API 키";
OverlayApiKeyHint.Text = "외부 호출에 필요한 키를 입력합니다.";
break;
default:
OverlayEndpointLabel.Text = "기본 서버 주소";
OverlayEndpointHint.Text = "Claude는 기본 주소를 사용합니다. 비워두면 기본값을 사용합니다.";
OverlayEndpointHint.Text = "Claude는 내부 기본 주소를 사용합니다.";
OverlayApiKeyLabel.Text = "Claude API 키";
OverlayApiKeyHint.Text = "외부 호출에 필요한 키를 입력합니다.";
break;
}
}
private void RefreshOverlayServiceFieldVisibility(string service)
{
if (OverlayEndpointFieldPanel == null || OverlayApiKeyFieldPanel == null)
return;
var hideEndpoint = string.Equals(service, "gemini", StringComparison.OrdinalIgnoreCase)
|| string.Equals(service, "claude", StringComparison.OrdinalIgnoreCase);
OverlayEndpointFieldPanel.Visibility = hideEndpoint ? Visibility.Collapsed : Visibility.Visible;
OverlayApiKeyFieldPanel.Margin = hideEndpoint ? new Thickness(0) : new Thickness(6, 0, 0, 0);
Grid.SetColumn(OverlayApiKeyFieldPanel, hideEndpoint ? 0 : 1);
Grid.SetColumnSpan(OverlayApiKeyFieldPanel, hideEndpoint ? 2 : 1);
}
private string GetOverlayServiceEndpoint(string service)
{
var llm = _settings.Settings.Llm;
@@ -16793,6 +16808,7 @@ public partial class ChatWindow : Window
? preferredModel
: candidates.FirstOrDefault().Id ?? llm.Model;
PersistOverlaySettingsState(refreshOverlayDeferredInputs: true);
RefreshOverlayVisualState(loadDeferredInputs: true);
}
private void BtnOverlayOperationMode_Click(object sender, RoutedEventArgs e)