feat(settings): per-model effort and turn presets
ClaudeDo never passed --effort, so every session inherited whatever effortLevel the user's Claude Code config happened to carry. Settings -> General now holds one row per model alias (haiku medium/20, sonnet high/30, opus high/40, fable high/25) supplying the global effort and turn defaults; list- and task-level max-turns overrides still win, and the agent editor's inherited badge follows the model. --effort is applied to autonomous runs and to every ConPTY spec (task session, planning start/resume, ad-hoc, list handler). The model itself is deliberately not forced on interactive sessions. The single global 'Max turns' field is replaced by the table, and 'fable' joins ModelRegistry.Aliases. The migration also adds the is_manual columns used by the next commit.
This commit is contained in:
@@ -27,6 +27,23 @@ public sealed partial class GeneralSettingsTabViewModel : ViewModelBase
|
||||
|
||||
public ObservableCollection<SelectableSkillViewModel> SessionSkills { get; } = new();
|
||||
|
||||
/// <summary>One editable row per model alias: the effort and turn budget a run gets under that
|
||||
/// model. Supplies the global defaults; list- and task-level max-turns overrides still win.</summary>
|
||||
public ObservableCollection<ModelPresetRowViewModel> ModelPresets { get; } = new();
|
||||
|
||||
public void LoadModelPresets(IReadOnlyCollection<ModelPresetDto>? presets)
|
||||
{
|
||||
ModelPresets.Clear();
|
||||
var source = presets is { Count: > 0 }
|
||||
? presets.Select(p => new ModelPreset(p.Model, p.Effort, p.MaxTurns)).ToList()
|
||||
: Data.Models.ModelPresets.Defaults.ToList();
|
||||
foreach (var p in Data.Models.ModelPresets.Parse(Data.Models.ModelPresets.Serialize(source)))
|
||||
ModelPresets.Add(new ModelPresetRowViewModel(p));
|
||||
}
|
||||
|
||||
public List<ModelPresetDto> ModelPresetDtos()
|
||||
=> ModelPresets.Select(r => new ModelPresetDto(r.Model, r.Effort, (int)r.MaxTurns)).ToList();
|
||||
|
||||
public GeneralSettingsTabViewModel() { }
|
||||
|
||||
public GeneralSettingsTabViewModel(ILocalizer localizer, Action<string> persist)
|
||||
@@ -50,10 +67,11 @@ public sealed partial class GeneralSettingsTabViewModel : ViewModelBase
|
||||
|
||||
public string? Validate()
|
||||
{
|
||||
if (DefaultMaxTurns < 1 || DefaultMaxTurns > 200)
|
||||
return "Max turns must be between 1 and 200.";
|
||||
if (MaxParallelExecutions < 1 || MaxParallelExecutions > 20)
|
||||
return "Max parallel executions must be between 1 and 20.";
|
||||
foreach (var row in ModelPresets)
|
||||
if (row.MaxTurns is < 1 or > 200)
|
||||
return $"Max turns for {row.Model} must be between 1 and 200.";
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -73,3 +91,21 @@ public sealed partial class GeneralSettingsTabViewModel : ViewModelBase
|
||||
return names.Count == 0 ? null : names;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>One row of the per-model preset table. Single consumer, so it lives here.</summary>
|
||||
public sealed partial class ModelPresetRowViewModel : ViewModelBase
|
||||
{
|
||||
public string Model { get; }
|
||||
public IReadOnlyList<string> EffortLevels { get; } = EffortRegistry.Levels;
|
||||
|
||||
[ObservableProperty] private string _effort;
|
||||
// decimal so it binds straight to a NumericUpDown, like the other numeric settings.
|
||||
[ObservableProperty] private decimal _maxTurns;
|
||||
|
||||
public ModelPresetRowViewModel(ModelPreset preset)
|
||||
{
|
||||
Model = preset.Model;
|
||||
_effort = preset.Effort;
|
||||
_maxTurns = preset.MaxTurns;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user