feat(ui): add config override fields to TaskEditorView
Adds Model, SystemPrompt, and AgentPath override fields to TaskEditorViewModel and TaskEditorView. Wires agent loading from WorkerClient in TaskListViewModel before opening the editor dialog. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using ClaudeDo.Data.Models;
|
using ClaudeDo.Data.Models;
|
||||||
|
using ClaudeDo.Ui.Services;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using TaskStatus = ClaudeDo.Data.Models.TaskStatus;
|
using TaskStatus = ClaudeDo.Data.Models.TaskStatus;
|
||||||
@@ -13,6 +14,10 @@ public partial class TaskEditorViewModel : ViewModelBase
|
|||||||
[ObservableProperty] private string _statusChoice = "manual";
|
[ObservableProperty] private string _statusChoice = "manual";
|
||||||
[ObservableProperty] private string _tagsInput = "";
|
[ObservableProperty] private string _tagsInput = "";
|
||||||
[ObservableProperty] private string _windowTitle = "New Task";
|
[ObservableProperty] private string _windowTitle = "New Task";
|
||||||
|
[ObservableProperty] private string _modelChoice = "(list default)";
|
||||||
|
[ObservableProperty] private string? _systemPromptOverride;
|
||||||
|
[ObservableProperty] private AgentInfo? _selectedAgent;
|
||||||
|
public List<AgentInfo> AvailableAgents { get; set; } = [];
|
||||||
|
|
||||||
private string? _editId;
|
private string? _editId;
|
||||||
private string _listId = "";
|
private string _listId = "";
|
||||||
@@ -21,12 +26,19 @@ public partial class TaskEditorViewModel : ViewModelBase
|
|||||||
|
|
||||||
public event Action? RequestClose;
|
public event Action? RequestClose;
|
||||||
|
|
||||||
|
public static string[] ModelChoices { get; } = ["(list default)", "Sonnet", "Opus", "Haiku"];
|
||||||
|
|
||||||
public static string[] CommitTypes { get; } =
|
public static string[] CommitTypes { get; } =
|
||||||
["chore", "feat", "fix", "refactor", "docs", "test", "perf", "style", "build", "ci"];
|
["chore", "feat", "fix", "refactor", "docs", "test", "perf", "style", "build", "ci"];
|
||||||
|
|
||||||
public static string[] StatusChoices { get; } =
|
public static string[] StatusChoices { get; } =
|
||||||
["manual", "queued"];
|
["manual", "queued"];
|
||||||
|
|
||||||
|
public async Task LoadAgentsAsync(WorkerClient worker)
|
||||||
|
{
|
||||||
|
AvailableAgents = await worker.GetAgentsAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public IReadOnlyList<string> SelectedTagNames =>
|
public IReadOnlyList<string> SelectedTagNames =>
|
||||||
TagsInput.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
TagsInput.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
@@ -56,6 +68,13 @@ public partial class TaskEditorViewModel : ViewModelBase
|
|||||||
_ => entity.Status.ToString().ToLowerInvariant(),
|
_ => entity.Status.ToString().ToLowerInvariant(),
|
||||||
};
|
};
|
||||||
TagsInput = string.Join(", ", taskTags.Select(t => t.Name));
|
TagsInput = string.Join(", ", taskTags.Select(t => t.Name));
|
||||||
|
ModelChoice = entity.Model is not null
|
||||||
|
? ListEditorViewModel.ModelIdToDisplay(entity.Model)
|
||||||
|
: "(list default)";
|
||||||
|
SystemPromptOverride = entity.SystemPrompt;
|
||||||
|
SelectedAgent = entity.AgentPath is not null
|
||||||
|
? AvailableAgents.FirstOrDefault(a => a.Path == entity.AgentPath)
|
||||||
|
: null;
|
||||||
WindowTitle = $"Edit Task: {entity.Title}";
|
WindowTitle = $"Edit Task: {entity.Title}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +97,11 @@ public partial class TaskEditorViewModel : ViewModelBase
|
|||||||
CommitType = CommitType,
|
CommitType = CommitType,
|
||||||
CreatedAt = _createdAt,
|
CreatedAt = _createdAt,
|
||||||
};
|
};
|
||||||
|
entity.Model = ModelChoice != "(list default)"
|
||||||
|
? ListEditorViewModel.ModelDisplayToId(ModelChoice)
|
||||||
|
: null;
|
||||||
|
entity.SystemPrompt = string.IsNullOrWhiteSpace(SystemPromptOverride) ? null : SystemPromptOverride.Trim();
|
||||||
|
entity.AgentPath = SelectedAgent?.Path;
|
||||||
_tcs.TrySetResult(entity);
|
_tcs.TrySetResult(entity);
|
||||||
RequestClose?.Invoke();
|
RequestClose?.Invoke();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ public partial class TaskListViewModel : ViewModelBase
|
|||||||
var defaultCommitType = list?.DefaultCommitType ?? "chore";
|
var defaultCommitType = list?.DefaultCommitType ?? "chore";
|
||||||
|
|
||||||
var editor = _editorFactory();
|
var editor = _editorFactory();
|
||||||
|
await editor.LoadAgentsAsync(_worker);
|
||||||
editor.InitForCreate(CurrentListId, defaultCommitType);
|
editor.InitForCreate(CurrentListId, defaultCommitType);
|
||||||
|
|
||||||
var window = new TaskEditorView { DataContext = editor };
|
var window = new TaskEditorView { DataContext = editor };
|
||||||
@@ -191,6 +192,7 @@ public partial class TaskListViewModel : ViewModelBase
|
|||||||
|
|
||||||
var taskTags = await _taskRepo.GetTagsAsync(entity.Id);
|
var taskTags = await _taskRepo.GetTagsAsync(entity.Id);
|
||||||
var editor = _editorFactory();
|
var editor = _editorFactory();
|
||||||
|
await editor.LoadAgentsAsync(_worker);
|
||||||
editor.InitForEdit(entity, taskTags);
|
editor.InitForEdit(entity, taskTags);
|
||||||
|
|
||||||
var window = new TaskEditorView { DataContext = editor };
|
var window = new TaskEditorView { DataContext = editor };
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
<Window xmlns="https://github.com/avaloniaui"
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:vm="using:ClaudeDo.Ui.ViewModels"
|
xmlns:vm="using:ClaudeDo.Ui.ViewModels"
|
||||||
|
xmlns:models="using:ClaudeDo.Data.Models"
|
||||||
x:Class="ClaudeDo.Ui.Views.TaskEditorView"
|
x:Class="ClaudeDo.Ui.Views.TaskEditorView"
|
||||||
x:DataType="vm:TaskEditorViewModel"
|
x:DataType="vm:TaskEditorViewModel"
|
||||||
Title="{Binding WindowTitle}"
|
Title="{Binding WindowTitle}"
|
||||||
Width="500" Height="420"
|
Width="500" Height="600"
|
||||||
WindowStartupLocation="CenterOwner"
|
WindowStartupLocation="CenterOwner"
|
||||||
CanResize="False"
|
CanResize="False"
|
||||||
Background="{StaticResource WindowBgBrush}">
|
Background="{StaticResource WindowBgBrush}">
|
||||||
@@ -34,6 +35,36 @@
|
|||||||
<TextBlock Text="Tags (comma-separated)" FontWeight="SemiBold" Foreground="{StaticResource TextSecondaryBrush}"/>
|
<TextBlock Text="Tags (comma-separated)" FontWeight="SemiBold" Foreground="{StaticResource TextSecondaryBrush}"/>
|
||||||
<TextBox Text="{Binding TagsInput}" PlaceholderText="agent, manual, code, ..."/>
|
<TextBox Text="{Binding TagsInput}" PlaceholderText="agent, manual, code, ..."/>
|
||||||
|
|
||||||
|
<!-- Divider -->
|
||||||
|
<Border Height="1" Background="{StaticResource BorderSubtleBrush}" Margin="0,6,0,2"/>
|
||||||
|
|
||||||
|
<TextBlock Text="Agent Config (overrides)" FontWeight="Bold" FontSize="13"
|
||||||
|
Foreground="{StaticResource TextPrimaryBrush}"/>
|
||||||
|
|
||||||
|
<TextBlock Text="Model" FontWeight="SemiBold"
|
||||||
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
||||||
|
<ComboBox ItemsSource="{Binding ModelChoices}"
|
||||||
|
SelectedItem="{Binding ModelChoice}"
|
||||||
|
MinWidth="150"/>
|
||||||
|
|
||||||
|
<TextBlock Text="System Prompt" FontWeight="SemiBold"
|
||||||
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
||||||
|
<TextBox Text="{Binding SystemPromptOverride}"
|
||||||
|
PlaceholderText="(inherits from list)"
|
||||||
|
AcceptsReturn="True" TextWrapping="Wrap" MinHeight="50"/>
|
||||||
|
|
||||||
|
<TextBlock Text="Agent File" FontWeight="SemiBold"
|
||||||
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
||||||
|
<ComboBox ItemsSource="{Binding AvailableAgents}"
|
||||||
|
SelectedItem="{Binding SelectedAgent}"
|
||||||
|
MinWidth="150">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="models:AgentInfo">
|
||||||
|
<TextBlock Text="{Binding Name}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8" HorizontalAlignment="Right" Margin="0,10,0,0">
|
<StackPanel Orientation="Horizontal" Spacing="8" HorizontalAlignment="Right" Margin="0,10,0,0">
|
||||||
<Button Content="Save" Command="{Binding SaveCommand}" IsDefault="True" MinWidth="80"
|
<Button Content="Save" Command="{Binding SaveCommand}" IsDefault="True" MinWidth="80"
|
||||||
Background="{StaticResource AccentBrush}" Foreground="{StaticResource TextPrimaryBrush}"/>
|
Background="{StaticResource AccentBrush}" Foreground="{StaticResource TextPrimaryBrush}"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user