feat(ui): show inherited markers and max-turns override in list settings
This commit is contained in:
@@ -28,12 +28,21 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
|
|||||||
[ObservableProperty] private string _workingDir = "";
|
[ObservableProperty] private string _workingDir = "";
|
||||||
[ObservableProperty] private string _defaultCommitType = CommitTypeRegistry.DefaultType;
|
[ObservableProperty] private string _defaultCommitType = CommitTypeRegistry.DefaultType;
|
||||||
|
|
||||||
[ObservableProperty] private string _selectedModel = ModelRegistry.ListDefaultSentinel;
|
[ObservableProperty] private string? _selectedModel; // null = inherit from global
|
||||||
|
[ObservableProperty] private decimal? _maxTurns; // null = inherit from global
|
||||||
|
[ObservableProperty] private string _modelInheritedHint = ""; // resolved value placeholder, e.g. "sonnet"
|
||||||
|
[ObservableProperty] private string _modelBadge = "";
|
||||||
|
[ObservableProperty] private string _turnsInheritedHint = "";
|
||||||
|
[ObservableProperty] private string _turnsBadge = "";
|
||||||
|
[ObservableProperty] private string _agentBadge = "";
|
||||||
|
|
||||||
[ObservableProperty] private string _systemPrompt = "";
|
[ObservableProperty] private string _systemPrompt = "";
|
||||||
[ObservableProperty] private AgentInfo? _selectedAgent;
|
[ObservableProperty] private AgentInfo? _selectedAgent;
|
||||||
|
|
||||||
public ObservableCollection<string> ModelOptions { get; } = new(
|
private string _globalModel = ModelRegistry.DefaultAlias;
|
||||||
new[] { ModelRegistry.ListDefaultSentinel }.Concat(ModelRegistry.Aliases));
|
private int _globalMaxTurns = 100;
|
||||||
|
|
||||||
|
public ObservableCollection<string> ModelOptions { get; } = new(ModelRegistry.Aliases);
|
||||||
|
|
||||||
public ObservableCollection<string> CommitTypeOptions { get; } = new(CommitTypeRegistry.Types);
|
public ObservableCollection<string> CommitTypeOptions { get; } = new(CommitTypeRegistry.Types);
|
||||||
|
|
||||||
@@ -47,6 +56,34 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
|
|||||||
_dbFactory = dbFactory;
|
_dbFactory = dbFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void OnSelectedModelChanged(string? value) => RecomputeModelBadge();
|
||||||
|
partial void OnMaxTurnsChanged(decimal? value) => RecomputeTurnsBadge();
|
||||||
|
partial void OnSelectedAgentChanged(AgentInfo? value) => RecomputeAgentBadge();
|
||||||
|
|
||||||
|
private void RecomputeModelBadge()
|
||||||
|
{
|
||||||
|
ModelInheritedHint = _globalModel;
|
||||||
|
ModelBadge = !string.IsNullOrWhiteSpace(SelectedModel)
|
||||||
|
? Loc.T("settings.inherit.overrideBadge")
|
||||||
|
: Loc.T("settings.inherit.inheritedFromGlobal");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecomputeTurnsBadge()
|
||||||
|
{
|
||||||
|
TurnsInheritedHint = _globalMaxTurns.ToString();
|
||||||
|
TurnsBadge = MaxTurns is not null
|
||||||
|
? Loc.T("settings.inherit.overrideBadge")
|
||||||
|
: Loc.T("settings.inherit.inheritedFromGlobal");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecomputeAgentBadge()
|
||||||
|
{
|
||||||
|
var overridden = SelectedAgent is not null && !string.IsNullOrWhiteSpace(SelectedAgent.Path);
|
||||||
|
AgentBadge = overridden
|
||||||
|
? Loc.T("settings.inherit.overrideBadge")
|
||||||
|
: Loc.T("settings.inherit.inheritedFromGlobal");
|
||||||
|
}
|
||||||
|
|
||||||
public async Task LoadAsync(
|
public async Task LoadAsync(
|
||||||
string listId,
|
string listId,
|
||||||
string name,
|
string name,
|
||||||
@@ -65,19 +102,30 @@ 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) ? ModelRegistry.ListDefaultSentinel : config!.Model!;
|
|
||||||
|
var app = await _worker.GetAppSettingsAsync();
|
||||||
|
_globalModel = app?.DefaultModel ?? ModelRegistry.DefaultAlias;
|
||||||
|
_globalMaxTurns = app?.DefaultMaxTurns ?? 100;
|
||||||
|
|
||||||
|
SelectedModel = string.IsNullOrWhiteSpace(config?.Model) ? null : config!.Model!;
|
||||||
|
MaxTurns = config?.MaxTurns is int mt ? mt : (decimal?)null;
|
||||||
SystemPrompt = config?.SystemPrompt ?? "";
|
SystemPrompt = config?.SystemPrompt ?? "";
|
||||||
SelectedAgent = string.IsNullOrWhiteSpace(config?.AgentPath)
|
SelectedAgent = string.IsNullOrWhiteSpace(config?.AgentPath)
|
||||||
? Agents[0]
|
? Agents[0]
|
||||||
: (Agents.FirstOrDefault(a => a.Path == config!.AgentPath) ?? Agents[0]);
|
: (Agents.FirstOrDefault(a => a.Path == config!.AgentPath) ?? Agents[0]);
|
||||||
|
|
||||||
|
RecomputeModelBadge();
|
||||||
|
RecomputeTurnsBadge();
|
||||||
|
RecomputeAgentBadge();
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async Task SaveAsync()
|
private async Task SaveAsync()
|
||||||
{
|
{
|
||||||
var model = SelectedModel == ModelRegistry.ListDefaultSentinel ? null : SelectedModel;
|
var model = string.IsNullOrWhiteSpace(SelectedModel) ? 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;
|
||||||
|
var turns = MaxTurns is decimal d ? (int?)d : null;
|
||||||
|
|
||||||
await _worker.UpdateListAsync(new UpdateListDto(
|
await _worker.UpdateListAsync(new UpdateListDto(
|
||||||
ListId,
|
ListId,
|
||||||
@@ -85,8 +133,7 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
|
|||||||
string.IsNullOrWhiteSpace(WorkingDir) ? null : WorkingDir,
|
string.IsNullOrWhiteSpace(WorkingDir) ? null : WorkingDir,
|
||||||
DefaultCommitType));
|
DefaultCommitType));
|
||||||
|
|
||||||
await _worker.UpdateListConfigAsync(new UpdateListConfigDto(
|
await _worker.UpdateListConfigAsync(new UpdateListConfigDto(ListId, model, sp, ap, turns));
|
||||||
ListId, model, sp, ap));
|
|
||||||
|
|
||||||
CloseAction?.Invoke();
|
CloseAction?.Invoke();
|
||||||
}
|
}
|
||||||
@@ -125,10 +172,15 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase
|
|||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private void Cancel() => CloseAction?.Invoke();
|
private void Cancel() => CloseAction?.Invoke();
|
||||||
|
|
||||||
|
[RelayCommand] private void ResetModel() => SelectedModel = null;
|
||||||
|
[RelayCommand] private void ResetTurns() => MaxTurns = null;
|
||||||
|
[RelayCommand] private void ResetAgent() => SelectedAgent = Agents.Count > 0 ? Agents[0] : null;
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private void ResetAgentSettings()
|
private void ResetAgentSettings()
|
||||||
{
|
{
|
||||||
SelectedModel = ModelRegistry.ListDefaultSentinel;
|
SelectedModel = null;
|
||||||
|
MaxTurns = null;
|
||||||
SystemPrompt = "";
|
SystemPrompt = "";
|
||||||
SelectedAgent = Agents.Count > 0 ? Agents[0] : null;
|
SelectedAgent = Agents.Count > 0 ? Agents[0] : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,12 +74,31 @@
|
|||||||
<Border Classes="section">
|
<Border Classes="section">
|
||||||
<StackPanel Spacing="12">
|
<StackPanel Spacing="12">
|
||||||
<StackPanel Spacing="4">
|
<StackPanel Spacing="4">
|
||||||
<TextBlock Classes="field-label" Text="{loc:Tr modals.listSettings.model}"/>
|
<Grid ColumnDefinitions="Auto,Auto,*,Auto" ColumnSpacing="6">
|
||||||
|
<TextBlock Grid.Column="0" Classes="field-label" Text="{loc:Tr modals.listSettings.model}" VerticalAlignment="Center"/>
|
||||||
|
<ctl:InheritedBadge Grid.Column="1" BadgeText="{Binding ModelBadge}"/>
|
||||||
|
<Button Grid.Column="3" Classes="btn" Content="↺" ToolTip.Tip="{loc:Tr settings.inherit.resetToInherited}"
|
||||||
|
Command="{Binding ResetModelCommand}" Padding="6,1"/>
|
||||||
|
</Grid>
|
||||||
<ComboBox ItemsSource="{Binding ModelOptions}"
|
<ComboBox ItemsSource="{Binding ModelOptions}"
|
||||||
SelectedItem="{Binding SelectedModel, Mode=TwoWay}"
|
SelectedItem="{Binding SelectedModel, Mode=TwoWay}"
|
||||||
|
PlaceholderText="{Binding ModelInheritedHint}"
|
||||||
HorizontalAlignment="Left" MinWidth="160" />
|
HorizontalAlignment="Left" MinWidth="160" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Spacing="4">
|
||||||
|
<Grid ColumnDefinitions="Auto,Auto,*,Auto" ColumnSpacing="6">
|
||||||
|
<TextBlock Grid.Column="0" Classes="field-label" Text="{loc:Tr modals.listSettings.maxTurns}" VerticalAlignment="Center"/>
|
||||||
|
<ctl:InheritedBadge Grid.Column="1" BadgeText="{Binding TurnsBadge}"/>
|
||||||
|
<Button Grid.Column="3" Classes="btn" Content="↺" ToolTip.Tip="{loc:Tr settings.inherit.resetToInherited}"
|
||||||
|
Command="{Binding ResetTurnsCommand}" Padding="6,1"/>
|
||||||
|
</Grid>
|
||||||
|
<NumericUpDown Value="{Binding MaxTurns, Mode=TwoWay}"
|
||||||
|
PlaceholderText="{Binding TurnsInheritedHint}"
|
||||||
|
Minimum="1" Maximum="200" Increment="1" FormatString="0"
|
||||||
|
HorizontalAlignment="Left" Width="160"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Spacing="4">
|
<StackPanel Spacing="4">
|
||||||
<TextBlock Classes="field-label" Text="{loc:Tr modals.listSettings.systemPrompt}"/>
|
<TextBlock Classes="field-label" Text="{loc:Tr modals.listSettings.systemPrompt}"/>
|
||||||
<TextBox Text="{Binding SystemPrompt, Mode=TwoWay}"
|
<TextBox Text="{Binding SystemPrompt, Mode=TwoWay}"
|
||||||
@@ -88,7 +107,12 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Spacing="4">
|
<StackPanel Spacing="4">
|
||||||
<TextBlock Classes="field-label" Text="{loc:Tr modals.listSettings.agentFile}"/>
|
<Grid ColumnDefinitions="Auto,Auto,*,Auto" ColumnSpacing="6">
|
||||||
|
<TextBlock Grid.Column="0" Classes="field-label" Text="{loc:Tr modals.listSettings.agentFile}" VerticalAlignment="Center"/>
|
||||||
|
<ctl:InheritedBadge Grid.Column="1" BadgeText="{Binding AgentBadge}"/>
|
||||||
|
<Button Grid.Column="3" Classes="btn" Content="↺" ToolTip.Tip="{loc:Tr settings.inherit.resetToInherited}"
|
||||||
|
Command="{Binding ResetAgentCommand}" Padding="6,1"/>
|
||||||
|
</Grid>
|
||||||
<Grid ColumnDefinitions="*,Auto">
|
<Grid ColumnDefinitions="*,Auto">
|
||||||
<ComboBox Grid.Column="0"
|
<ComboBox Grid.Column="0"
|
||||||
ItemsSource="{Binding Agents}"
|
ItemsSource="{Binding Agents}"
|
||||||
|
|||||||
Reference in New Issue
Block a user