[Phase46] 대형 파일 분할 리팩터링 2차 — 19개 신규 파셜 파일 생성
## 분할 대상 및 결과 ### AgentLoopService.cs (1,334줄 → 846줄) - AgentLoopService.HtmlReport.cs (151줄): AutoSaveAsHtml, ConvertTextToHtml, EscapeHtml - AgentLoopService.Verification.cs (349줄): 도구 분류 판별 + RunPostToolVerificationAsync + EmitEvent + CheckDecisionRequired + FormatToolCallSummary ### ChatWindow 분할 (8개 신규 파셜 파일) - ChatWindow.PlanViewer.cs (474줄): 계획 뷰어 — AddPlanningCard, AddDecisionButtons, CollapseDecisionButtons, ShowPlanButton 등 8개 메서드 - ChatWindow.EventBanner.cs (411줄): AddAgentEventBanner, BuildFileQuickActions - ChatWindow.TaskDecomposition.cs (1,170줄 → 307줄): RenderSuggestActionChips, BuildFeedbackContext, UpdateProgressBar, BuildDiffView 잔류 - ChatWindow.BottomBar.cs (345줄): BuildBottomBar, BuildCodeBottomBar, ShowLogLevelMenu, ShowLanguageMenu 등 - ChatWindow.MoodMenu.cs (456줄): ShowFormatMenu, ShowMoodMenu, ShowCustomMoodDialog 등 - ChatWindow.CustomPresets.cs (978줄 → 203줄): ShowCustomPresetDialog, SelectTopic 잔류 - ChatWindow.ConversationMenu.cs (255줄): ShowConversationMenu (카테고리/삭제/즐겨찾기 팝업) - ChatWindow.ConversationTitleEdit.cs (108줄): EnterTitleEditMode ### SettingsViewModel 분할 - SettingsViewModel.LlmProperties.cs (417줄): LLM·에이전트 관련 바인딩 프로퍼티 - SettingsViewModel.Properties.cs (837줄 → 427줄): 기능 토글·테마·스니펫 등 앱 수준 프로퍼티 ### TemplateService 분할 - TemplateService.Css.cs (559줄): 11종 CSS 테마 문자열 상수 - TemplateService.cs (734줄 → 179줄): 메서드 로직만 잔류 ### PlanViewerWindow 분할 - PlanViewerWindow.StepRenderer.cs (616줄): RenderSteps + SwapSteps + EditStep + 버튼 빌더 9개 - PlanViewerWindow.cs (931줄 → 324줄): Win32/생성자/공개 API 잔류 ### App.xaml.cs 분할 (776줄 → 452줄) - App.Settings.cs (252줄): SetupTrayIcon, OpenSettings, ToggleDockBar, RefreshDockBar, OpenAiChat - App.Helpers.cs (92줄): LoadAppIcon, IsAutoStartEnabled, SetAutoStart, OnExit ### LlmService.ToolUse.cs 분할 (719줄 → 115줄) - LlmService.ClaudeTools.cs (180줄): SendClaudeWithToolsAsync, BuildClaudeToolBody - LlmService.GeminiTools.cs (175줄): SendGeminiWithToolsAsync, BuildGeminiToolBody - LlmService.OpenAiTools.cs (215줄): SendOpenAiWithToolsAsync, BuildOpenAiToolBody ### SettingsWindow.UI.cs 분할 (802줄 → 310줄) - SettingsWindow.Storage.cs (167줄): RefreshStorageInfo, BtnStorageCleanup_Click 등 - SettingsWindow.HotkeyUI.cs (127줄): RefreshHotkeyBadges, EnsureHotkeyInCombo, GetKeyName 등 - SettingsWindow.DevMode.cs (90줄): DevModeCheckBox_Checked, UpdateDevModeContentVisibility ## 빌드 결과: 경고 0, 오류 0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
417
src/AxCopilot/ViewModels/SettingsViewModel.LlmProperties.cs
Normal file
417
src/AxCopilot/ViewModels/SettingsViewModel.LlmProperties.cs
Normal file
@@ -0,0 +1,417 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using AxCopilot.Models;
|
||||
|
||||
namespace AxCopilot.ViewModels;
|
||||
|
||||
public partial class SettingsViewModel
|
||||
{
|
||||
/// <summary>CodeSettings 바인딩용 프로퍼티. XAML에서 {Binding Code.EnableLsp} 등으로 접근.</summary>
|
||||
public Models.CodeSettings Code => _service.Settings.Llm.Code;
|
||||
|
||||
// ─── 등록 모델 목록 ───────────────────────────────────────────────────
|
||||
public ObservableCollection<RegisteredModelRow> RegisteredModels { get; } = new();
|
||||
|
||||
public string LlmService
|
||||
{
|
||||
get => _llmService;
|
||||
set { _llmService = value; OnPropertyChanged(); OnPropertyChanged(nameof(IsInternalService)); OnPropertyChanged(nameof(IsExternalService)); OnPropertyChanged(nameof(NeedsEndpoint)); OnPropertyChanged(nameof(NeedsApiKey)); OnPropertyChanged(nameof(IsGeminiSelected)); OnPropertyChanged(nameof(IsClaudeSelected)); }
|
||||
}
|
||||
public bool IsInternalService => _llmService is "ollama" or "vllm";
|
||||
public bool IsExternalService => _llmService is "gemini" or "claude";
|
||||
public bool NeedsEndpoint => _llmService is "ollama" or "vllm";
|
||||
public bool NeedsApiKey => _llmService is not "ollama";
|
||||
public bool IsGeminiSelected => _llmService == "gemini";
|
||||
public bool IsClaudeSelected => _llmService == "claude";
|
||||
|
||||
// ── Ollama 설정 ──
|
||||
public string OllamaEndpoint { get => _ollamaEndpoint; set { _ollamaEndpoint = value; OnPropertyChanged(); } }
|
||||
public string OllamaApiKey { get => _ollamaApiKey; set { _ollamaApiKey = value; OnPropertyChanged(); } }
|
||||
public string OllamaModel { get => _ollamaModel; set { _ollamaModel = value; OnPropertyChanged(); } }
|
||||
|
||||
// ── vLLM 설정 ──
|
||||
public string VllmEndpoint { get => _vllmEndpoint; set { _vllmEndpoint = value; OnPropertyChanged(); } }
|
||||
public string VllmApiKey { get => _vllmApiKey; set { _vllmApiKey = value; OnPropertyChanged(); } }
|
||||
public string VllmModel { get => _vllmModel; set { _vllmModel = value; OnPropertyChanged(); } }
|
||||
|
||||
// ── Gemini 설정 ──
|
||||
public string GeminiApiKey { get => _geminiApiKey; set { _geminiApiKey = value; OnPropertyChanged(); } }
|
||||
public string GeminiModel { get => _geminiModel; set { _geminiModel = value; OnPropertyChanged(); } }
|
||||
|
||||
// ── Claude 설정 ──
|
||||
public string ClaudeApiKey { get => _claudeApiKey; set { _claudeApiKey = value; OnPropertyChanged(); } }
|
||||
public string ClaudeModel { get => _claudeModel; set { _claudeModel = value; OnPropertyChanged(); } }
|
||||
|
||||
// ── 공통 응답 설정 ──
|
||||
public bool LlmStreaming
|
||||
{
|
||||
get => _llmStreaming;
|
||||
set { _llmStreaming = value; OnPropertyChanged(); }
|
||||
}
|
||||
public int LlmMaxContextTokens
|
||||
{
|
||||
get => _llmMaxContextTokens;
|
||||
set { _llmMaxContextTokens = value; OnPropertyChanged(); }
|
||||
}
|
||||
public int LlmRetentionDays
|
||||
{
|
||||
get => _llmRetentionDays;
|
||||
set { _llmRetentionDays = value; OnPropertyChanged(); }
|
||||
}
|
||||
public double LlmTemperature
|
||||
{
|
||||
get => _llmTemperature;
|
||||
set { _llmTemperature = Math.Round(Math.Clamp(value, 0.0, 2.0), 1); OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// 에이전트 기본 파일 접근 권한
|
||||
private string _defaultAgentPermission;
|
||||
public string DefaultAgentPermission
|
||||
{
|
||||
get => _defaultAgentPermission;
|
||||
set { _defaultAgentPermission = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// ── 코워크/에이전트 고급 설정 ──
|
||||
private string _defaultOutputFormat;
|
||||
public string DefaultOutputFormat
|
||||
{
|
||||
get => _defaultOutputFormat;
|
||||
set { _defaultOutputFormat = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private string _autoPreview;
|
||||
public string AutoPreview
|
||||
{
|
||||
get => _autoPreview;
|
||||
set { _autoPreview = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private int _maxAgentIterations;
|
||||
public int MaxAgentIterations
|
||||
{
|
||||
get => _maxAgentIterations;
|
||||
set { _maxAgentIterations = Math.Clamp(value, 1, 100); OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private int _maxRetryOnError;
|
||||
public int MaxRetryOnError
|
||||
{
|
||||
get => _maxRetryOnError;
|
||||
set { _maxRetryOnError = Math.Clamp(value, 0, 10); OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private string _agentLogLevel;
|
||||
public string AgentLogLevel
|
||||
{
|
||||
get => _agentLogLevel;
|
||||
set { _agentLogLevel = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private string _agentDecisionLevel = "detailed";
|
||||
public string AgentDecisionLevel
|
||||
{
|
||||
get => _agentDecisionLevel;
|
||||
set { _agentDecisionLevel = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private string _planMode = "off";
|
||||
public string PlanMode
|
||||
{
|
||||
get => _planMode;
|
||||
set { _planMode = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _enableMultiPassDocument;
|
||||
public bool EnableMultiPassDocument
|
||||
{
|
||||
get => _enableMultiPassDocument;
|
||||
set { _enableMultiPassDocument = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _enableCoworkVerification;
|
||||
public bool EnableCoworkVerification
|
||||
{
|
||||
get => _enableCoworkVerification;
|
||||
set { _enableCoworkVerification = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _enableFilePathHighlight = true;
|
||||
public bool EnableFilePathHighlight
|
||||
{
|
||||
get => _enableFilePathHighlight;
|
||||
set { _enableFilePathHighlight = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private string _folderDataUsage;
|
||||
public string FolderDataUsage
|
||||
{
|
||||
get => _folderDataUsage;
|
||||
set { _folderDataUsage = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// ── 모델 폴백 + 보안 + MCP ──
|
||||
private bool _enableAuditLog;
|
||||
public bool EnableAuditLog
|
||||
{
|
||||
get => _enableAuditLog;
|
||||
set { _enableAuditLog = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _enableAgentMemory;
|
||||
public bool EnableAgentMemory
|
||||
{
|
||||
get => _enableAgentMemory;
|
||||
set { _enableAgentMemory = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _enableProjectRules = true;
|
||||
public bool EnableProjectRules
|
||||
{
|
||||
get => _enableProjectRules;
|
||||
set { _enableProjectRules = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private int _maxMemoryEntries;
|
||||
public int MaxMemoryEntries
|
||||
{
|
||||
get => _maxMemoryEntries;
|
||||
set { _maxMemoryEntries = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// ── 이미지 입력 (멀티모달) ──
|
||||
private bool _enableImageInput = true;
|
||||
public bool EnableImageInput
|
||||
{
|
||||
get => _enableImageInput;
|
||||
set { _enableImageInput = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private int _maxImageSizeKb = 5120;
|
||||
public int MaxImageSizeKb
|
||||
{
|
||||
get => _maxImageSizeKb;
|
||||
set { _maxImageSizeKb = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// ── 자동 모델 라우팅 ──
|
||||
private bool _enableAutoRouter;
|
||||
public bool EnableAutoRouter
|
||||
{
|
||||
get => _enableAutoRouter;
|
||||
set { _enableAutoRouter = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private double _autoRouterConfidence = 0.7;
|
||||
public double AutoRouterConfidence
|
||||
{
|
||||
get => _autoRouterConfidence;
|
||||
set { _autoRouterConfidence = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// ── 에이전트 훅 시스템 ──
|
||||
private bool _enableToolHooks = true;
|
||||
public bool EnableToolHooks
|
||||
{
|
||||
get => _enableToolHooks;
|
||||
set { _enableToolHooks = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private int _toolHookTimeoutMs = 10000;
|
||||
public int ToolHookTimeoutMs
|
||||
{
|
||||
get => _toolHookTimeoutMs;
|
||||
set { _toolHookTimeoutMs = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// ── 스킬 시스템 ──
|
||||
private bool _enableSkillSystem = true;
|
||||
public bool EnableSkillSystem
|
||||
{
|
||||
get => _enableSkillSystem;
|
||||
set { _enableSkillSystem = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private string _skillsFolderPath = "";
|
||||
public string SkillsFolderPath
|
||||
{
|
||||
get => _skillsFolderPath;
|
||||
set { _skillsFolderPath = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private int _slashPopupPageSize = 6;
|
||||
public int SlashPopupPageSize
|
||||
{
|
||||
get => _slashPopupPageSize;
|
||||
set { _slashPopupPageSize = Math.Clamp(value, 3, 10); OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// ── 드래그&드롭 AI ──
|
||||
private bool _enableDragDropAiActions = true;
|
||||
public bool EnableDragDropAiActions
|
||||
{
|
||||
get => _enableDragDropAiActions;
|
||||
set { _enableDragDropAiActions = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _dragDropAutoSend;
|
||||
public bool DragDropAutoSend
|
||||
{
|
||||
get => _dragDropAutoSend;
|
||||
set { _dragDropAutoSend = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// ── 코드 리뷰 ──
|
||||
private bool _enableCodeReview = true;
|
||||
public bool EnableCodeReview
|
||||
{
|
||||
get => _enableCodeReview;
|
||||
set { _enableCodeReview = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// ── 시각 효과 + 알림 + 개발자 모드 (공통) ──
|
||||
private bool _enableChatRainbowGlow;
|
||||
public bool EnableChatRainbowGlow
|
||||
{
|
||||
get => _enableChatRainbowGlow;
|
||||
set { _enableChatRainbowGlow = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _notifyOnComplete;
|
||||
public bool NotifyOnComplete
|
||||
{
|
||||
get => _notifyOnComplete;
|
||||
set { _notifyOnComplete = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _showTips;
|
||||
public bool ShowTips
|
||||
{
|
||||
get => _showTips;
|
||||
set { _showTips = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _devMode;
|
||||
public bool DevMode
|
||||
{
|
||||
get => _devMode;
|
||||
set { _devMode = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _devModeStepApproval;
|
||||
public bool DevModeStepApproval
|
||||
{
|
||||
get => _devModeStepApproval;
|
||||
set { _devModeStepApproval = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _workflowVisualizer;
|
||||
public bool WorkflowVisualizer
|
||||
{
|
||||
get => _workflowVisualizer;
|
||||
set { _workflowVisualizer = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _freeTierMode;
|
||||
public bool FreeTierMode
|
||||
{
|
||||
get => _freeTierMode;
|
||||
set { _freeTierMode = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private int _freeTierDelaySeconds = 4;
|
||||
public int FreeTierDelaySeconds
|
||||
{
|
||||
get => _freeTierDelaySeconds;
|
||||
set { _freeTierDelaySeconds = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _showTotalCallStats;
|
||||
public bool ShowTotalCallStats
|
||||
{
|
||||
get => _showTotalCallStats;
|
||||
set { _showTotalCallStats = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private string _defaultMood = "modern";
|
||||
public string DefaultMood
|
||||
{
|
||||
get => _defaultMood;
|
||||
set { _defaultMood = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// 차단 경로/확장자 (읽기 전용 UI)
|
||||
public ObservableCollection<string> BlockedPaths { get; } = new();
|
||||
public ObservableCollection<string> BlockedExtensions { get; } = new();
|
||||
|
||||
public string Hotkey
|
||||
{
|
||||
get => _hotkey;
|
||||
set { _hotkey = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
public int MaxResults
|
||||
{
|
||||
get => _maxResults;
|
||||
set { _maxResults = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
public double Opacity
|
||||
{
|
||||
get => _opacity;
|
||||
set { _opacity = value; OnPropertyChanged(); OnPropertyChanged(nameof(OpacityPercent)); }
|
||||
}
|
||||
|
||||
public int OpacityPercent => (int)Math.Round(_opacity * 100);
|
||||
|
||||
public string SelectedThemeKey
|
||||
{
|
||||
get => _selectedThemeKey;
|
||||
set
|
||||
{
|
||||
_selectedThemeKey = value;
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(IsCustomTheme));
|
||||
foreach (var card in ThemeCards)
|
||||
card.IsSelected = card.Key == value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCustomTheme => _selectedThemeKey == "custom";
|
||||
|
||||
public string LauncherPosition
|
||||
{
|
||||
get => _launcherPosition;
|
||||
set { _launcherPosition = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
public string WebSearchEngine
|
||||
{
|
||||
get => _webSearchEngine;
|
||||
set { _webSearchEngine = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
public bool SnippetAutoExpand
|
||||
{
|
||||
get => _snippetAutoExpand;
|
||||
set { _snippetAutoExpand = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
public string Language
|
||||
{
|
||||
get => _language;
|
||||
set { _language = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
public string IndexSpeed
|
||||
{
|
||||
get => _indexSpeed;
|
||||
set { _indexSpeed = value; OnPropertyChanged(); OnPropertyChanged(nameof(IndexSpeedHint)); }
|
||||
}
|
||||
|
||||
public string IndexSpeedHint => _indexSpeed switch
|
||||
{
|
||||
"fast" => "CPU 사용률이 높아질 수 있습니다. 고성능 PC에 권장합니다.",
|
||||
"slow" => "인덱싱이 오래 걸리지만 PC 성능에 영향을 주지 않습니다.",
|
||||
_ => "일반적인 PC에 적합한 균형 설정입니다.",
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user