모델 프로파일 기반 Cowork/Code 루프와 진행 UX 고도화 반영

- 등록 모델 실행 프로파일을 검증 게이트, 문서 fallback, post-tool verification까지 확장 적용

- Cowork/Code 진행 카드에 계획/도구/검증/압축/폴백/재시도 단계 메타를 추가해 대기 상태 가시성 강화

- OpenAI/vLLM tool 요청에 병렬 도구 호출 힌트를 추가하고 회귀 프롬프트 문서를 프로파일 기준으로 전면 정리

- 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ (경고 0 / 오류 0)
This commit is contained in:
2026-04-08 13:41:57 +09:00
parent b391dfdfb3
commit a2c952879d
552 changed files with 8094 additions and 13595 deletions

View File

@@ -76,20 +76,37 @@ public partial class LauncherViewModel
private int _widgetRefreshTick;
public void UpdateWidgets()
=> UpdateWidgets(true, true, true, true, true);
public void UpdateWidgets(
bool includePerf,
bool includePomo,
bool includeNote,
bool includeCalendar,
bool includeServerStatus)
{
_widgetRefreshTick++;
if (_widgetRefreshTick % 5 == 0)
if (includeNote && _widgetRefreshTick % 5 == 0)
_widgetNoteCount = GetNoteCount();
OnPropertyChanged(nameof(Widget_PerfText));
OnPropertyChanged(nameof(Widget_PomoText));
OnPropertyChanged(nameof(Widget_PomoRunning));
OnPropertyChanged(nameof(Widget_NoteText));
OnPropertyChanged(nameof(Widget_OllamaOnline));
OnPropertyChanged(nameof(Widget_LlmOnline));
OnPropertyChanged(nameof(Widget_McpOnline));
OnPropertyChanged(nameof(Widget_McpName));
OnPropertyChanged(nameof(Widget_CalText));
if (includePerf)
OnPropertyChanged(nameof(Widget_PerfText));
if (includePomo)
{
OnPropertyChanged(nameof(Widget_PomoText));
OnPropertyChanged(nameof(Widget_PomoRunning));
}
if (includeNote)
OnPropertyChanged(nameof(Widget_NoteText));
if (includeServerStatus)
{
OnPropertyChanged(nameof(Widget_OllamaOnline));
OnPropertyChanged(nameof(Widget_LlmOnline));
OnPropertyChanged(nameof(Widget_McpOnline));
OnPropertyChanged(nameof(Widget_McpName));
}
if (includeCalendar)
OnPropertyChanged(nameof(Widget_CalText));
}
private static int GetNoteCount()

View File

@@ -1245,6 +1245,7 @@ public class SettingsViewModel : INotifyPropertyChanged
Alias = rm.Alias,
EncryptedModelName = rm.EncryptedModelName,
Service = rm.Service,
ExecutionProfile = rm.ExecutionProfile ?? "balanced",
Endpoint = rm.Endpoint,
ApiKey = rm.ApiKey,
AllowInsecureTls = rm.AllowInsecureTls,
@@ -1679,6 +1680,7 @@ public class SettingsViewModel : INotifyPropertyChanged
Alias = rm.Alias,
EncryptedModelName = rm.EncryptedModelName,
Service = rm.Service,
ExecutionProfile = rm.ExecutionProfile ?? "balanced",
Endpoint = rm.Endpoint,
ApiKey = rm.ApiKey,
AllowInsecureTls = rm.AllowInsecureTls,
@@ -1998,6 +2000,7 @@ public class RegisteredModelRow : INotifyPropertyChanged
private string _alias = "";
private string _encryptedModelName = "";
private string _service = "ollama";
private string _executionProfile = "balanced";
private string _endpoint = "";
private string _apiKey = "";
private bool _allowInsecureTls;
@@ -2023,6 +2026,12 @@ public class RegisteredModelRow : INotifyPropertyChanged
set { _service = value; OnPropertyChanged(); OnPropertyChanged(nameof(ServiceLabel)); }
}
public string ExecutionProfile
{
get => _executionProfile;
set { _executionProfile = value; OnPropertyChanged(); OnPropertyChanged(nameof(ProfileLabel)); }
}
/// <summary>이 모델 전용 서버 엔드포인트. 비어있으면 기본 엔드포인트 사용.</summary>
public string Endpoint
{
@@ -2098,6 +2107,15 @@ public class RegisteredModelRow : INotifyPropertyChanged
/// <summary>서비스 라벨</summary>
public string ServiceLabel => _service == "vllm" ? "vLLM" : "Ollama";
public string ProfileLabel => (_executionProfile ?? "balanced").Trim().ToLowerInvariant() switch
{
"tool_call_strict" => "도구 호출 우선",
"reasoning_first" => "추론 우선",
"fast_readonly" => "읽기 속도 우선",
"document_heavy" => "문서 생성 우선",
_ => "균형",
};
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? n = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(n));