feat(ui): show inherited markers and max-turns override in task flyout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -138,28 +138,60 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
||||
OnPropertyChanged(nameof(ShowContinue));
|
||||
OnPropertyChanged(nameof(ShowResetAndRetry));
|
||||
OnPropertyChanged(nameof(IsAgentSectionEnabled));
|
||||
OnPropertyChanged(nameof(EffectiveModelLabel));
|
||||
OnPropertyChanged(nameof(EffectiveAgentLabel));
|
||||
}
|
||||
[ObservableProperty] private string? _model;
|
||||
|
||||
// Agent settings overrides
|
||||
[ObservableProperty] private string _taskModelSelection = ModelRegistry.TaskInheritSentinel;
|
||||
[ObservableProperty] private string? _taskModelSelection; // null = inherit
|
||||
[ObservableProperty] private string _taskSystemPrompt = "";
|
||||
[ObservableProperty] private AgentInfo? _taskSelectedAgent;
|
||||
|
||||
[ObservableProperty] private string _effectiveModelHint = "";
|
||||
[ObservableProperty] private decimal? _taskMaxTurns; // null = inherit
|
||||
[ObservableProperty] private string _modelBadge = "";
|
||||
[ObservableProperty] private string _modelInheritedHint = "";
|
||||
[ObservableProperty] private string _turnsBadge = "";
|
||||
[ObservableProperty] private string _turnsInheritedHint = "";
|
||||
[ObservableProperty] private string _agentBadge = "";
|
||||
[ObservableProperty] private string _effectiveSystemPromptHint = "";
|
||||
[ObservableProperty] private string _effectiveAgentHint = "";
|
||||
|
||||
public string EffectiveModelLabel => Loc.T("vm.details.effectiveIfInherited", EffectiveModelHint);
|
||||
public string EffectiveAgentLabel => Loc.T("vm.details.effectiveIfInherited", EffectiveAgentHint);
|
||||
private string _globalModel = ModelRegistry.DefaultAlias;
|
||||
private int _globalMaxTurns = 100;
|
||||
private string? _listModel;
|
||||
private int? _listMaxTurns;
|
||||
private string? _listAgentName;
|
||||
|
||||
partial void OnEffectiveModelHintChanged(string value) => OnPropertyChanged(nameof(EffectiveModelLabel));
|
||||
partial void OnEffectiveAgentHintChanged(string value) => OnPropertyChanged(nameof(EffectiveAgentLabel));
|
||||
partial void OnTaskModelSelectionChanged(string? value) { RecomputeModelBadge(); QueueAgentSave(); }
|
||||
partial void OnTaskMaxTurnsChanged(decimal? value) { RecomputeTurnsBadge(); QueueAgentSave(); }
|
||||
|
||||
public System.Collections.ObjectModel.ObservableCollection<string> TaskModelOptions { get; } = new(
|
||||
new[] { ModelRegistry.TaskInheritSentinel }.Concat(ModelRegistry.Aliases));
|
||||
private void RecomputeModelBadge()
|
||||
{
|
||||
var (value, source) = InheritanceResolver.Resolve(TaskModelSelection, _listModel, _globalModel);
|
||||
ModelInheritedHint = value;
|
||||
ModelBadge = BadgeFor(source, !string.IsNullOrWhiteSpace(TaskModelSelection));
|
||||
}
|
||||
|
||||
private void RecomputeTurnsBadge()
|
||||
{
|
||||
var (value, source) = InheritanceResolver.Resolve(
|
||||
TaskMaxTurns?.ToString(), _listMaxTurns?.ToString(), _globalMaxTurns.ToString());
|
||||
TurnsInheritedHint = value;
|
||||
TurnsBadge = BadgeFor(source, TaskMaxTurns is not null);
|
||||
}
|
||||
|
||||
private void RecomputeAgentBadge()
|
||||
{
|
||||
var taskSet = TaskSelectedAgent is not null && !string.IsNullOrWhiteSpace(TaskSelectedAgent.Path);
|
||||
var (_, source) = InheritanceResolver.Resolve(
|
||||
taskSet ? TaskSelectedAgent!.Path : null, _listAgentName, null);
|
||||
AgentBadge = BadgeFor(source, taskSet);
|
||||
}
|
||||
|
||||
private static string BadgeFor(InheritSource source, bool taskSet) => taskSet
|
||||
? Loc.T("settings.inherit.overrideBadge")
|
||||
: source == InheritSource.List
|
||||
? Loc.T("settings.inherit.inheritedFromList")
|
||||
: Loc.T("settings.inherit.inheritedFromGlobal");
|
||||
|
||||
public System.Collections.ObjectModel.ObservableCollection<string> TaskModelOptions { get; } = new(ModelRegistry.Aliases);
|
||||
|
||||
public System.Collections.ObjectModel.ObservableCollection<AgentInfo> TaskAgentOptions { get; } = new();
|
||||
|
||||
@@ -288,8 +320,9 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
||||
Loc.LanguageChanged += (_, _) =>
|
||||
{
|
||||
OnPropertyChanged(nameof(AgentStatusLabel));
|
||||
OnPropertyChanged(nameof(EffectiveModelLabel));
|
||||
OnPropertyChanged(nameof(EffectiveAgentLabel));
|
||||
RecomputeModelBadge();
|
||||
RecomputeTurnsBadge();
|
||||
RecomputeAgentBadge();
|
||||
};
|
||||
|
||||
// Subscribe once; filter by current task id inside the handler
|
||||
@@ -433,9 +466,8 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
||||
Log.Add(new LogLineViewModel { Kind = LogKind.Claude, Text = piece });
|
||||
}
|
||||
|
||||
partial void OnTaskModelSelectionChanged(string value) => QueueAgentSave();
|
||||
partial void OnTaskSystemPromptChanged(string value) => QueueAgentSave();
|
||||
partial void OnTaskSelectedAgentChanged(AgentInfo? value) => QueueAgentSave();
|
||||
partial void OnTaskSelectedAgentChanged(AgentInfo? value) { RecomputeAgentBadge(); QueueAgentSave(); }
|
||||
|
||||
partial void OnEditableDescriptionChanged(string value)
|
||||
{
|
||||
@@ -478,13 +510,14 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
||||
await System.Threading.Tasks.Task.Delay(300, ct);
|
||||
if (Task is null) return;
|
||||
|
||||
var model = TaskModelSelection == ModelRegistry.TaskInheritSentinel ? null : TaskModelSelection;
|
||||
var model = string.IsNullOrWhiteSpace(TaskModelSelection) ? null : TaskModelSelection;
|
||||
var sp = string.IsNullOrWhiteSpace(TaskSystemPrompt) ? null : TaskSystemPrompt;
|
||||
var ap = TaskSelectedAgent is null || string.IsNullOrWhiteSpace(TaskSelectedAgent.Path)
|
||||
? null : TaskSelectedAgent.Path;
|
||||
var turns = TaskMaxTurns is decimal d ? (int?)d : null;
|
||||
|
||||
await _worker.UpdateTaskAgentSettingsAsync(
|
||||
new ClaudeDo.Ui.Services.UpdateTaskAgentSettingsDto(Task.Id, model, sp, ap));
|
||||
new ClaudeDo.Ui.Services.UpdateTaskAgentSettingsDto(Task.Id, model, sp, ap, turns));
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch { }
|
||||
@@ -497,21 +530,31 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
||||
try
|
||||
{
|
||||
TaskAgentOptions.Clear();
|
||||
TaskAgentOptions.Add(new AgentInfo(ModelRegistry.TaskInheritSentinel, "", ""));
|
||||
TaskAgentOptions.Add(new AgentInfo("(inherited)", "", ""));
|
||||
var agents = await _worker.GetAgentsAsync();
|
||||
foreach (var a in agents) TaskAgentOptions.Add(a);
|
||||
|
||||
TaskModelSelection = string.IsNullOrWhiteSpace(entity.Model) ? ModelRegistry.TaskInheritSentinel : entity.Model!;
|
||||
TaskModelSelection = string.IsNullOrWhiteSpace(entity.Model) ? null : entity.Model!;
|
||||
TaskMaxTurns = entity.MaxTurns is int tmt ? tmt : (decimal?)null;
|
||||
TaskSystemPrompt = entity.SystemPrompt ?? "";
|
||||
TaskSelectedAgent = string.IsNullOrWhiteSpace(entity.AgentPath)
|
||||
? TaskAgentOptions[0]
|
||||
: (TaskAgentOptions.FirstOrDefault(a => a.Path == entity.AgentPath) ?? TaskAgentOptions[0]);
|
||||
|
||||
var listCfg = await _worker.GetListConfigAsync(entity.ListId);
|
||||
EffectiveModelHint = string.IsNullOrWhiteSpace(listCfg?.Model) ? "(global default)" : listCfg!.Model!;
|
||||
EffectiveSystemPromptHint = string.IsNullOrWhiteSpace(listCfg?.SystemPrompt) ? "(none)" : listCfg!.SystemPrompt!;
|
||||
EffectiveAgentHint = string.IsNullOrWhiteSpace(listCfg?.AgentPath)
|
||||
? "(none)" : System.IO.Path.GetFileName(listCfg!.AgentPath!);
|
||||
var app = await _worker.GetAppSettingsAsync();
|
||||
_globalModel = app?.DefaultModel ?? ModelRegistry.DefaultAlias;
|
||||
_globalMaxTurns = app?.DefaultMaxTurns ?? 100;
|
||||
_listModel = listCfg?.Model;
|
||||
_listMaxTurns = listCfg?.MaxTurns;
|
||||
_listAgentName = string.IsNullOrWhiteSpace(listCfg?.AgentPath)
|
||||
? null : System.IO.Path.GetFileName(listCfg!.AgentPath!);
|
||||
|
||||
EffectiveSystemPromptHint = string.IsNullOrWhiteSpace(listCfg?.SystemPrompt) ? "" : listCfg!.SystemPrompt!;
|
||||
|
||||
RecomputeModelBadge();
|
||||
RecomputeTurnsBadge();
|
||||
RecomputeAgentBadge();
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -583,7 +626,8 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
||||
_suppressAgentSave = true;
|
||||
try
|
||||
{
|
||||
TaskModelSelection = ModelRegistry.TaskInheritSentinel;
|
||||
TaskModelSelection = null;
|
||||
TaskMaxTurns = null;
|
||||
TaskSystemPrompt = "";
|
||||
TaskSelectedAgent = null;
|
||||
}
|
||||
@@ -591,9 +635,7 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
||||
{
|
||||
_suppressAgentSave = false;
|
||||
}
|
||||
EffectiveModelHint = "";
|
||||
EffectiveSystemPromptHint = "";
|
||||
EffectiveAgentHint = "";
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1085,6 +1127,10 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
||||
|
||||
private bool CanResetAndRetry() =>
|
||||
Task != null && _worker.IsConnected && ShowResetAndRetry;
|
||||
|
||||
[RelayCommand] private void ResetTaskModel() => TaskModelSelection = null;
|
||||
[RelayCommand] private void ResetTaskTurns() => TaskMaxTurns = null;
|
||||
[RelayCommand] private void ResetTaskAgent() => TaskSelectedAgent = TaskAgentOptions.Count > 0 ? TaskAgentOptions[0] : null;
|
||||
}
|
||||
|
||||
public sealed partial class SubtaskRowViewModel : ViewModelBase
|
||||
|
||||
Reference in New Issue
Block a user