Files
AX-Copilot/src/AxCopilot/Views/Controls/AgentSettingsPanel.xaml
lacvet 23d1534536 [v2.0.0] AgentSettingsPanel 기능 완성 — 서비스·모델·작업폴더·MCP
AgentSettingsPanel.xaml.cs:
- BtnServiceSelector_Click: ServiceSelectorRequested 콜백 실행 (ChatWindow 위임)
- BtnModelSelector_Click: ModelSelectorRequested 콜백 실행 (ChatWindow 위임)
- ServiceSelectorRequested / ModelSelectorRequested / WorkFolderBrowseRequested Action 추가
- LoadFromSettings: UpdateWorkFolder() + BuildMcpServerList() 호출 추가
- LoadFromSettings: PanelWorkFolder 가시성 제어 추가
- UpdateActiveTab: PanelWorkFolder 가시성 제어 추가
- BtnWorkFolderBrowse_Click, UpdateWorkFolder, BuildMcpServerList, McpToggle_Changed 추가
- using System.Linq / using AxCopilot.Models 추가

AgentSettingsPanel.xaml:
- PanelWorkFolder 섹션 추가 (Code 탭 전용 — 폴더 표시 + 탐색 버튼)
- PanelMcpServers 섹션 추가 (도구 관리 뒤, 고급 앞)

ChatWindow.MoodMenu.cs:
- ToggleSettingsPanel(): 패널 열 때 ServiceSelector/ModelSelector/WorkFolder 콜백 연결

빌드: 경고 0, 오류 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 08:38:51 +09:00

405 lines
24 KiB
XML

<UserControl x:Class="AxCopilot.Views.Controls.AgentSettingsPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="300" MinWidth="280">
<!-- Phase 32-A: 우측 슬라이드인 설정 패널 (CC Claude.ai 스타일)
ChatWindow 내부에서 AX Agent 모든 설정을 인라인으로 제어.
SettingsWindow의 AX Agent 탭을 완전 대체. -->
<UserControl.RenderTransform>
<TranslateTransform x:Name="SlideTransform" X="300"/>
</UserControl.RenderTransform>
<Border Background="{DynamicResource LauncherBackground}"
BorderBrush="{DynamicResource BorderColor}"
BorderThickness="1,0,0,0"
CornerRadius="0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 헤더: 설정 타이틀 + 닫기 -->
<Border Grid.Row="0" BorderBrush="{DynamicResource BorderColor}" BorderThickness="0,0,0,1">
<Grid Margin="16,0">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Text="&#xE713;" FontFamily="Segoe MDL2 Assets" FontSize="16"
Foreground="{DynamicResource AccentColor}" VerticalAlignment="Center"/>
<TextBlock Text=" 설정" FontSize="15" FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}" VerticalAlignment="Center" Margin="6,0,0,0"/>
</StackPanel>
<Border HorizontalAlignment="Right" VerticalAlignment="Center"
Background="Transparent" Cursor="Hand" Padding="8,4"
CornerRadius="4" MouseLeftButtonUp="BtnClose_Click">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#18FFFFFF"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="&#xE8BB;" FontFamily="Segoe MDL2 Assets" FontSize="12"
Foreground="{DynamicResource SecondaryText}"/>
</Border>
</Grid>
</Border>
<!-- 설정 본문: 스크롤 가능 -->
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled" Padding="0,0,2,0">
<StackPanel Margin="16,12,16,20">
<!-- 현재 탭 표시 -->
<Border Background="{DynamicResource ItemBackground}" CornerRadius="8" Padding="12,8" Margin="0,0,0,16">
<StackPanel Orientation="Horizontal">
<TextBlock Text="현재 탭:" Foreground="{DynamicResource SecondaryText}" FontSize="12"/>
<TextBlock x:Name="TxtCurrentTab" Text="Chat" FontSize="12" FontWeight="SemiBold"
Foreground="{DynamicResource AccentColor}" Margin="6,0,0,0"/>
</StackPanel>
</Border>
<!-- ═══ 모델 & 서비스 ═══ -->
<TextBlock Text="모델 &amp; 서비스" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
<!-- LLM 서비스 -->
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="LLM 서비스" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<Border Grid.Column="1" Background="{DynamicResource ItemBackground}"
CornerRadius="6" Padding="10,6" Cursor="Hand"
MouseLeftButtonUp="BtnServiceSelector_Click">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource ItemHoverBackground}"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid>
<TextBlock x:Name="TxtServiceName" Text="Ollama" FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
<TextBlock Text="&#xE70D;" FontFamily="Segoe MDL2 Assets" FontSize="10"
Foreground="{DynamicResource SecondaryText}"
HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
</Border>
</Grid>
<!-- 모델 -->
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="모델" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<Border Grid.Column="1" Background="{DynamicResource ItemBackground}"
CornerRadius="6" Padding="10,6" Cursor="Hand"
MouseLeftButtonUp="BtnModelSelector_Click">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource ItemHoverBackground}"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid>
<TextBlock x:Name="TxtModelName" Text="llama3:8b" FontSize="12"
Foreground="{DynamicResource PrimaryText}"/>
<TextBlock Text="&#xE70D;" FontFamily="Segoe MDL2 Assets" FontSize="10"
Foreground="{DynamicResource SecondaryText}"
HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
</Border>
</Grid>
<!-- API 엔드포인트 -->
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="API 엔드포인트" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<TextBox x:Name="TxtApiEndpoint" FontSize="12" Padding="8,5"
Background="{DynamicResource ItemBackground}"
Foreground="{DynamicResource PrimaryText}"
BorderBrush="{DynamicResource BorderColor}"
BorderThickness="1" Grid.Column="1"
LostFocus="TxtApiEndpoint_LostFocus"/>
</Grid>
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
<!-- ═══ 에이전트 동작 ═══ -->
<TextBlock Text="에이전트 동작" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
<!-- 최대 반복 횟수 -->
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBlock Text="최대 반복 횟수" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<TextBlock x:Name="TxtMaxIterations" Grid.Column="1" Text="25"
Foreground="{DynamicResource PrimaryText}" FontSize="12"
HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
<Slider x:Name="SliderMaxIterations" Minimum="1" Maximum="100" Value="25"
IsSnapToTickEnabled="True" TickFrequency="1"
ValueChanged="SliderMaxIterations_ValueChanged" Margin="0,0,0,8"/>
<!-- 오류 시 재시도 -->
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBlock Text="오류 시 재시도" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<TextBlock x:Name="TxtMaxRetry" Grid.Column="1" Text="3"
Foreground="{DynamicResource PrimaryText}" FontSize="12"
HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
<Slider x:Name="SliderMaxRetry" Minimum="0" Maximum="10" Value="3"
IsSnapToTickEnabled="True" TickFrequency="1"
ValueChanged="SliderMaxRetry_ValueChanged" Margin="0,0,0,8"/>
<!-- 병렬 도구 실행 토글 -->
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="병렬 도구 실행" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<CheckBox x:Name="ChkParallelTools" Grid.Column="1"
Style="{StaticResource ToggleSwitch}"
Checked="ChkParallelTools_Changed" Unchecked="ChkParallelTools_Changed"/>
</Grid>
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
<!-- ═══ 자기성찰 메모리 (Phase 17-A) ═══ -->
<TextBlock Text="자기성찰 메모리" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
<!-- 자기성찰 활성화 -->
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel>
<TextBlock Text="자기성찰 메모리" Foreground="{DynamicResource SecondaryText}" FontSize="12"/>
<TextBlock Text="동일 유형 작업 시 과거 교훈 자동 참고" FontSize="10"
Foreground="{DynamicResource SecondaryText}" Opacity="0.7"/>
</StackPanel>
<CheckBox x:Name="ChkReflexionEnabled" Grid.Column="1"
Style="{StaticResource ToggleSwitch}"
Checked="ChkReflexion_Changed" Unchecked="ChkReflexion_Changed"/>
</Grid>
<!-- 성공 시만 평가 -->
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="성공 세션만 평가" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<CheckBox x:Name="ChkReflexionSuccessOnly" Grid.Column="1"
Style="{StaticResource ToggleSwitch}"
Checked="ChkReflexionSuccessOnly_Changed" Unchecked="ChkReflexionSuccessOnly_Changed"/>
</Grid>
<!-- 최대 참고 교훈 수 -->
<Grid Margin="0,0,0,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBlock Text="최대 참고 교훈 수" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<TextBlock x:Name="TxtReflexionMaxEntries" Grid.Column="1" Text="5"
Foreground="{DynamicResource PrimaryText}" FontSize="12"
HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
<Slider x:Name="SliderReflexionMaxEntries" Minimum="1" Maximum="20" Value="5"
IsSnapToTickEnabled="True" TickFrequency="1"
ValueChanged="SliderReflexionMaxEntries_ValueChanged" Margin="0,0,0,8"/>
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
<!-- ═══ 탭 전용 설정 ═══ -->
<TextBlock Text="탭 전용 설정" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
<!-- Cowork 전용 -->
<StackPanel x:Name="PanelCoworkSettings" Visibility="Collapsed">
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="검증 강제" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<CheckBox x:Name="ChkCoworkVerify" Grid.Column="1"
Style="{StaticResource ToggleSwitch}"
Checked="ChkCoworkVerify_Changed" Unchecked="ChkCoworkVerify_Changed"/>
</Grid>
</StackPanel>
<!-- Code 전용 -->
<StackPanel x:Name="PanelCodeSettings" Visibility="Collapsed">
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="LSP 분석" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<CheckBox x:Name="ChkCodeLsp" Grid.Column="1"
Style="{StaticResource ToggleSwitch}"
Checked="ChkCodeLsp_Changed" Unchecked="ChkCodeLsp_Changed"/>
</Grid>
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="코드 검증" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<CheckBox x:Name="ChkCodeVerify" Grid.Column="1"
Style="{StaticResource ToggleSwitch}"
Checked="ChkCodeVerify_Changed" Unchecked="ChkCodeVerify_Changed"/>
</Grid>
</StackPanel>
<!-- 작업 폴더 (Code 탭 전용) -->
<StackPanel x:Name="PanelWorkFolder" Visibility="Collapsed" Margin="0,8,0,0">
<Grid Margin="0,0,0,6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="작업 폴더" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
</Grid>
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border Background="{DynamicResource HintBackground}" CornerRadius="6" Padding="8,5">
<TextBlock x:Name="TxtWorkFolder" Text="(미지정)" FontSize="11"
Foreground="{DynamicResource SecondaryText}"
TextTrimming="CharacterEllipsis" MaxWidth="170"/>
</Border>
<Border Grid.Column="1" CornerRadius="6" Padding="10,5" Margin="6,0,0,0" Cursor="Hand"
MouseLeftButtonUp="BtnWorkFolderBrowse_Click">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{DynamicResource ItemBackground}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource ItemHoverBackground}"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="&#xE838;" FontFamily="Segoe MDL2 Assets" FontSize="12"
Foreground="#FFB74D" VerticalAlignment="Center"/>
</Border>
</Grid>
</StackPanel>
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
<!-- ═══ 도구 관리 ═══ -->
<TextBlock Text="도구 관리" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
<StackPanel x:Name="PanelToolToggles">
<!-- 코드비하인드에서 동적 생성 -->
</StackPanel>
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
<!-- ═══ MCP 서버 ═══ -->
<TextBlock Text="MCP 서버" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
<StackPanel x:Name="PanelMcpServers" Margin="0,0,0,8">
<!-- 코드비하인드에서 동적 생성 -->
</StackPanel>
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
<!-- ═══ 고급 ═══ -->
<TextBlock Text="고급" FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
<!-- 자동 컴팩션 임계치 -->
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBlock Text="자동 컴팩션 (%)" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<TextBlock x:Name="TxtAutoCompact" Grid.Column="1" Text="80"
Foreground="{DynamicResource PrimaryText}" FontSize="12"
HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
<Slider x:Name="SliderAutoCompact" Minimum="50" Maximum="95" Value="80"
IsSnapToTickEnabled="True" TickFrequency="5"
ValueChanged="SliderAutoCompact_ValueChanged" Margin="0,0,0,8"/>
<!-- 프로젝트 규칙 -->
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="프로젝트 규칙 (AX.md)" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<CheckBox x:Name="ChkProjectRules" Grid.Column="1"
Style="{StaticResource ToggleSwitch}" IsChecked="True"
Checked="ChkProjectRules_Changed" Unchecked="ChkProjectRules_Changed"/>
</Grid>
<!-- 개발자 모드 -->
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="개발자 모드" Foreground="{DynamicResource SecondaryText}" FontSize="12"
VerticalAlignment="Center"/>
<CheckBox x:Name="ChkDevMode" Grid.Column="1"
Style="{StaticResource ToggleSwitch}"
Checked="ChkDevMode_Changed" Unchecked="ChkDevMode_Changed"/>
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
</Border>
</UserControl>