refactor(config): consolidate model aliases into ModelRegistry
Replaces three scattered model lists (ListSettingsModalViewModel, DetailsIslandViewModel, GeneralSettingsTabViewModel) and the hardcoded planning model with a single source. Planning launcher now uses the opus alias instead of pinning claude-opus-4-7.
This commit is contained in:
12
src/ClaudeDo.Data/Models/ModelRegistry.cs
Normal file
12
src/ClaudeDo.Data/Models/ModelRegistry.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
namespace ClaudeDo.Data.Models;
|
||||||
|
|
||||||
|
public static class ModelRegistry
|
||||||
|
{
|
||||||
|
public static readonly IReadOnlyList<string> Aliases = new[] { "sonnet", "opus", "haiku" };
|
||||||
|
|
||||||
|
public const string DefaultAlias = "sonnet";
|
||||||
|
public const string PlanningAlias = "opus";
|
||||||
|
|
||||||
|
public const string ListDefaultSentinel = "(default)";
|
||||||
|
public const string TaskInheritSentinel = "(inherit)";
|
||||||
|
}
|
||||||
@@ -95,7 +95,7 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
|||||||
[ObservableProperty] private string? _model;
|
[ObservableProperty] private string? _model;
|
||||||
|
|
||||||
// Agent settings overrides
|
// Agent settings overrides
|
||||||
[ObservableProperty] private string _taskModelSelection = "(inherit)";
|
[ObservableProperty] private string _taskModelSelection = ModelRegistry.TaskInheritSentinel;
|
||||||
[ObservableProperty] private string _taskSystemPrompt = "";
|
[ObservableProperty] private string _taskSystemPrompt = "";
|
||||||
[ObservableProperty] private AgentInfo? _taskSelectedAgent;
|
[ObservableProperty] private AgentInfo? _taskSelectedAgent;
|
||||||
|
|
||||||
@@ -103,10 +103,8 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
|||||||
[ObservableProperty] private string _effectiveSystemPromptHint = "";
|
[ObservableProperty] private string _effectiveSystemPromptHint = "";
|
||||||
[ObservableProperty] private string _effectiveAgentHint = "";
|
[ObservableProperty] private string _effectiveAgentHint = "";
|
||||||
|
|
||||||
public System.Collections.ObjectModel.ObservableCollection<string> TaskModelOptions { get; } = new()
|
public System.Collections.ObjectModel.ObservableCollection<string> TaskModelOptions { get; } = new(
|
||||||
{
|
new[] { ModelRegistry.TaskInheritSentinel }.Concat(ModelRegistry.Aliases));
|
||||||
"(inherit)", "sonnet", "opus", "haiku",
|
|
||||||
};
|
|
||||||
|
|
||||||
public System.Collections.ObjectModel.ObservableCollection<AgentInfo> TaskAgentOptions { get; } = new();
|
public System.Collections.ObjectModel.ObservableCollection<AgentInfo> TaskAgentOptions { get; } = new();
|
||||||
|
|
||||||
@@ -365,7 +363,7 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
|||||||
await System.Threading.Tasks.Task.Delay(300, ct);
|
await System.Threading.Tasks.Task.Delay(300, ct);
|
||||||
if (Task is null) return;
|
if (Task is null) return;
|
||||||
|
|
||||||
var model = TaskModelSelection == "(inherit)" ? null : TaskModelSelection;
|
var model = TaskModelSelection == ModelRegistry.TaskInheritSentinel ? null : TaskModelSelection;
|
||||||
var sp = string.IsNullOrWhiteSpace(TaskSystemPrompt) ? null : TaskSystemPrompt;
|
var sp = string.IsNullOrWhiteSpace(TaskSystemPrompt) ? null : TaskSystemPrompt;
|
||||||
var ap = TaskSelectedAgent is null || string.IsNullOrWhiteSpace(TaskSelectedAgent.Path)
|
var ap = TaskSelectedAgent is null || string.IsNullOrWhiteSpace(TaskSelectedAgent.Path)
|
||||||
? null : TaskSelectedAgent.Path;
|
? null : TaskSelectedAgent.Path;
|
||||||
@@ -384,11 +382,11 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
TaskAgentOptions.Clear();
|
TaskAgentOptions.Clear();
|
||||||
TaskAgentOptions.Add(new AgentInfo("(inherit)", "", ""));
|
TaskAgentOptions.Add(new AgentInfo(ModelRegistry.TaskInheritSentinel, "", ""));
|
||||||
var agents = await _worker.GetAgentsAsync();
|
var agents = await _worker.GetAgentsAsync();
|
||||||
foreach (var a in agents) TaskAgentOptions.Add(a);
|
foreach (var a in agents) TaskAgentOptions.Add(a);
|
||||||
|
|
||||||
TaskModelSelection = string.IsNullOrWhiteSpace(entity.Model) ? "(inherit)" : entity.Model!;
|
TaskModelSelection = string.IsNullOrWhiteSpace(entity.Model) ? ModelRegistry.TaskInheritSentinel : entity.Model!;
|
||||||
TaskSystemPrompt = entity.SystemPrompt ?? "";
|
TaskSystemPrompt = entity.SystemPrompt ?? "";
|
||||||
TaskSelectedAgent = string.IsNullOrWhiteSpace(entity.AgentPath)
|
TaskSelectedAgent = string.IsNullOrWhiteSpace(entity.AgentPath)
|
||||||
? TaskAgentOptions[0]
|
? TaskAgentOptions[0]
|
||||||
@@ -439,7 +437,7 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
|||||||
_suppressAgentSave = true;
|
_suppressAgentSave = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
TaskModelSelection = "(inherit)";
|
TaskModelSelection = ModelRegistry.TaskInheritSentinel;
|
||||||
TaskSystemPrompt = "";
|
TaskSystemPrompt = "";
|
||||||
TaskSelectedAgent = null;
|
TaskSelectedAgent = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,14 +16,12 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
|
|||||||
[ObservableProperty] private string _workingDir = "";
|
[ObservableProperty] private string _workingDir = "";
|
||||||
[ObservableProperty] private string _defaultCommitType = "chore";
|
[ObservableProperty] private string _defaultCommitType = "chore";
|
||||||
|
|
||||||
[ObservableProperty] private string _selectedModel = "(default)";
|
[ObservableProperty] private string _selectedModel = ModelRegistry.ListDefaultSentinel;
|
||||||
[ObservableProperty] private string _systemPrompt = "";
|
[ObservableProperty] private string _systemPrompt = "";
|
||||||
[ObservableProperty] private AgentInfo? _selectedAgent;
|
[ObservableProperty] private AgentInfo? _selectedAgent;
|
||||||
|
|
||||||
public ObservableCollection<string> ModelOptions { get; } = new()
|
public ObservableCollection<string> ModelOptions { get; } = new(
|
||||||
{
|
new[] { ModelRegistry.ListDefaultSentinel }.Concat(ModelRegistry.Aliases));
|
||||||
"(default)", "sonnet", "opus", "haiku",
|
|
||||||
};
|
|
||||||
|
|
||||||
public ObservableCollection<string> CommitTypeOptions { get; } = new()
|
public ObservableCollection<string> CommitTypeOptions { get; } = new()
|
||||||
{
|
{
|
||||||
@@ -57,7 +55,7 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
|
|||||||
foreach (var a in agents) Agents.Add(a);
|
foreach (var a in agents) Agents.Add(a);
|
||||||
|
|
||||||
var config = await _worker.GetListConfigAsync(listId);
|
var config = await _worker.GetListConfigAsync(listId);
|
||||||
SelectedModel = string.IsNullOrWhiteSpace(config?.Model) ? "(default)" : config!.Model!;
|
SelectedModel = string.IsNullOrWhiteSpace(config?.Model) ? ModelRegistry.ListDefaultSentinel : config!.Model!;
|
||||||
SystemPrompt = config?.SystemPrompt ?? "";
|
SystemPrompt = config?.SystemPrompt ?? "";
|
||||||
SelectedAgent = string.IsNullOrWhiteSpace(config?.AgentPath)
|
SelectedAgent = string.IsNullOrWhiteSpace(config?.AgentPath)
|
||||||
? Agents[0]
|
? Agents[0]
|
||||||
@@ -67,7 +65,7 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
|
|||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async Task SaveAsync()
|
private async Task SaveAsync()
|
||||||
{
|
{
|
||||||
var model = SelectedModel == "(default)" ? null : SelectedModel;
|
var model = SelectedModel == ModelRegistry.ListDefaultSentinel ? null : SelectedModel;
|
||||||
var sp = string.IsNullOrWhiteSpace(SystemPrompt) ? null : SystemPrompt;
|
var sp = string.IsNullOrWhiteSpace(SystemPrompt) ? null : SystemPrompt;
|
||||||
var ap = SelectedAgent is null || string.IsNullOrWhiteSpace(SelectedAgent.Path) ? null : SelectedAgent.Path;
|
var ap = SelectedAgent is null || string.IsNullOrWhiteSpace(SelectedAgent.Path) ? null : SelectedAgent.Path;
|
||||||
|
|
||||||
@@ -89,7 +87,7 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
|
|||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private void ResetAgentSettings()
|
private void ResetAgentSettings()
|
||||||
{
|
{
|
||||||
SelectedModel = "(default)";
|
SelectedModel = ModelRegistry.ListDefaultSentinel;
|
||||||
SystemPrompt = "";
|
SystemPrompt = "";
|
||||||
SelectedAgent = Agents.Count > 0 ? Agents[0] : null;
|
SelectedAgent = Agents.Count > 0 ? Agents[0] : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using ClaudeDo.Data.Models;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
namespace ClaudeDo.Ui.ViewModels.Modals.Settings;
|
namespace ClaudeDo.Ui.ViewModels.Modals.Settings;
|
||||||
@@ -5,11 +6,11 @@ namespace ClaudeDo.Ui.ViewModels.Modals.Settings;
|
|||||||
public sealed partial class GeneralSettingsTabViewModel : ViewModelBase
|
public sealed partial class GeneralSettingsTabViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
[ObservableProperty] private string _defaultClaudeInstructions = "";
|
[ObservableProperty] private string _defaultClaudeInstructions = "";
|
||||||
[ObservableProperty] private string _defaultModel = "sonnet";
|
[ObservableProperty] private string _defaultModel = ModelRegistry.DefaultAlias;
|
||||||
[ObservableProperty] private int _defaultMaxTurns = 100;
|
[ObservableProperty] private int _defaultMaxTurns = 100;
|
||||||
[ObservableProperty] private string _defaultPermissionMode = "auto";
|
[ObservableProperty] private string _defaultPermissionMode = "auto";
|
||||||
|
|
||||||
public IReadOnlyList<string> Models { get; } = new[] { "opus", "sonnet", "haiku" };
|
public IReadOnlyList<string> Models { get; } = ModelRegistry.Aliases;
|
||||||
public IReadOnlyList<string> PermissionModes { get; } = new[]
|
public IReadOnlyList<string> PermissionModes { get; } = new[]
|
||||||
{ "auto", "bypassPermissions", "acceptEdits", "plan", "default" };
|
{ "auto", "bypassPermissions", "acceptEdits", "plan", "default" };
|
||||||
|
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
|||||||
{
|
{
|
||||||
Id = AppSettingsEntity.SingletonId,
|
Id = AppSettingsEntity.SingletonId,
|
||||||
DefaultClaudeInstructions = dto.DefaultClaudeInstructions ?? "",
|
DefaultClaudeInstructions = dto.DefaultClaudeInstructions ?? "",
|
||||||
DefaultModel = dto.DefaultModel ?? "sonnet",
|
DefaultModel = dto.DefaultModel ?? ModelRegistry.DefaultAlias,
|
||||||
DefaultMaxTurns = dto.DefaultMaxTurns,
|
DefaultMaxTurns = dto.DefaultMaxTurns,
|
||||||
DefaultPermissionMode = dto.DefaultPermissionMode ?? "bypassPermissions",
|
DefaultPermissionMode = dto.DefaultPermissionMode ?? "bypassPermissions",
|
||||||
WorktreeStrategy = dto.WorktreeStrategy ?? "sibling",
|
WorktreeStrategy = dto.WorktreeStrategy ?? "sibling",
|
||||||
|
|||||||
@@ -7,13 +7,14 @@
|
|||||||
// No cmd /k shim — arbitrary initial-prompt content would be re-parsed by cmd.exe otherwise.
|
// No cmd /k shim — arbitrary initial-prompt content would be re-parsed by cmd.exe otherwise.
|
||||||
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using ClaudeDo.Data.Models;
|
||||||
|
|
||||||
namespace ClaudeDo.Worker.Planning;
|
namespace ClaudeDo.Worker.Planning;
|
||||||
|
|
||||||
public sealed class WindowsTerminalPlanningLauncher : IPlanningTerminalLauncher
|
public sealed class WindowsTerminalPlanningLauncher : IPlanningTerminalLauncher
|
||||||
{
|
{
|
||||||
private const string AllowedTools = "mcp__claudedo__*,Read,Grep,Glob,WebFetch,WebSearch,Skill";
|
private const string AllowedTools = "mcp__claudedo__*,Read,Grep,Glob,WebFetch,WebSearch,Skill";
|
||||||
private const string Model = "claude-opus-4-7";
|
private const string Model = ModelRegistry.PlanningAlias;
|
||||||
|
|
||||||
private readonly string _wtPath;
|
private readonly string _wtPath;
|
||||||
private readonly string _claudePath;
|
private readonly string _claudePath;
|
||||||
|
|||||||
Reference in New Issue
Block a user