Bisher teilte sich eine Budgetablehnung den Ausgang NichtGelaufen mit dem Herunterfahren. Einmalige Aufgaben wurden den Rest des Tages alle 30 Minuten erneut abgelehnt (jedes Mal ein Beleg) und liefen nach Mitternacht still zu Lasten des neuen Tages. Wiederkehrende verfielen still. - TaskLauf.KeinBudget als eigener Ausgang; der Dispatcher bildet BudgetExceeded darauf ab. - Vier Felder an der Aufgabe: BudgetMissCount, LastBudgetMissAt, DeferredUntil, CatchUpPending (Spalten werden fuer bestehende Datenbanken nachgeruestet). - Einmalige Aufgaben werden mitgenommen: Der Termin bleibt erhalten, faellig ist die Aufgabe wieder ab der naechsten lokalen Mitternacht, nicht vorher. - Wiederkehrende Aufgaben folgen der Regel des Agenten (budget.whenExhausted): expire vermerkt den Ausfall und laesst den Termin verfallen; catchUpOnce fasst alle verpassten Termine zu einem Nachholauf am naechsten Tag zusammen. Ein regulaer faelliger Termin deckt das Nachholen mit ab, es bleibt bei einem Lauf. - Der neue Tag hat Vorfahrt: Mitgenommenes und Nachholaeufe kommen nach allem regulaer Faelligen, unabhaengig von der Prioritaet. - Beim ersten Takt eines neuen Tages eine Zusammenfassung je Agent im Log. - Sichtbar: Die Aufgabenkarte der WebUI zeigt Ausfaelle, Mitnahme und Nachholen; die Regel ist im Desktop je Agent einstellbar. Nebenbei sind "Next:"/"Last:" auf der Karte ins Sprachpaket gewandert. Stufen 2 bis 4 (Reservierung, Spielraum statt pauschalem Anteil, Vorbeugen) folgen. Tests: BudgetMissTests (9 neu). 1.238 gruen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
294 lines
15 KiB
XML
294 lines
15 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
xmlns:vm="using:ClawdDotNet.Desktop.ViewModels"
|
|
xmlns:ctrl="using:ClawdDotNet.Desktop.Controls"
|
|
mc:Ignorable="d" d:DesignWidth="1280" d:DesignHeight="820"
|
|
x:Class="ClawdDotNet.Desktop.Views.AgentsPageView"
|
|
x:DataType="vm:AgentsPageViewModel">
|
|
|
|
<!--
|
|
Vier Felder wie in der WinForms-Vorlage: oben Agentenliste und Agenteneinstellungen,
|
|
unten Werkzeugliste und Werkzeugeinstellungen — aber mit ziehbaren Teilern statt
|
|
fester SplitterDistance und mit flachen Feldern statt PropertyGrid.
|
|
|
|
Die Teilerstellungen werden im Code-Behind gelesen und gespeichert: ColumnDefinition
|
|
liegt nicht im Sichtbarkeitsbaum und erbt deshalb keinen DataContext — eine Bindung
|
|
darauf wuerde stillschweigend nichts tun.
|
|
-->
|
|
<DockPanel>
|
|
|
|
<TextBlock DockPanel.Dock="Bottom" Classes="caption" Margin="0,10,0,0"
|
|
Text="{Binding StatusText}" TextWrapping="Wrap" />
|
|
|
|
<Grid x:Name="OuterGrid" RowDefinitions="*,Auto,*">
|
|
|
|
<!-- ══════════════════ Oben: Agenten ══════════════════ -->
|
|
<Grid x:Name="TopGrid" Grid.Row="0" ColumnDefinitions="0.44*,Auto,0.56*">
|
|
|
|
<!-- Liste -->
|
|
<DockPanel Grid.Column="0" Margin="0,0,14,0">
|
|
|
|
<WrapPanel DockPanel.Dock="Top" Classes="toolbar">
|
|
<Button Classes="toolbar" Command="{Binding AddAgentCommand}">
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<ctrl:StrokeIcon Data="{StaticResource IconPlus}" Width="14" Height="14" />
|
|
<TextBlock Text="{Binding L[desktop.agents.addAgent]}" />
|
|
</StackPanel>
|
|
</Button>
|
|
|
|
<Button Classes="toolbar" Command="{Binding RemoveAgentCommand}"
|
|
IsEnabled="{Binding SelectedAgent, Converter={x:Static ObjectConverters.IsNotNull}}">
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<ctrl:StrokeIcon Data="{StaticResource IconMinus}" Width="14" Height="14" />
|
|
<TextBlock Text="{Binding L[desktop.agents.removeAgent]}" />
|
|
</StackPanel>
|
|
</Button>
|
|
|
|
<Border Classes="sep" />
|
|
|
|
<Button Classes="toolbar" Command="{Binding RunAgentNowCommand}"
|
|
IsEnabled="{Binding !IsRunning}">
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<ctrl:StrokeIcon Data="{StaticResource IconPlay}" Width="12" Height="12" IsFilled="True" />
|
|
<TextBlock Text="{Binding L[desktop.agents.runNow]}" />
|
|
</StackPanel>
|
|
</Button>
|
|
|
|
<Border Classes="sep" />
|
|
|
|
<Button Classes="toolbar" Command="{Binding EditIdentityCommand}"
|
|
IsEnabled="{Binding SelectedAgent, Converter={x:Static ObjectConverters.IsNotNull}}">
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<ctrl:StrokeIcon Data="{StaticResource IconPencil}" Width="14" Height="14" />
|
|
<TextBlock Text="{Binding L[desktop.agents.identity]}" />
|
|
</StackPanel>
|
|
</Button>
|
|
|
|
<Button Classes="toolbar" Command="{Binding EditSoulCommand}"
|
|
IsEnabled="{Binding SelectedAgent, Converter={x:Static ObjectConverters.IsNotNull}}">
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<ctrl:StrokeIcon Data="{StaticResource IconPencil}" Width="14" Height="14" />
|
|
<TextBlock Text="{Binding L[desktop.agents.soul]}" />
|
|
</StackPanel>
|
|
</Button>
|
|
|
|
<Border Classes="sep" />
|
|
|
|
<Button Classes="toolbar" Command="{Binding OpenAgentFolderCommand}"
|
|
IsEnabled="{Binding SelectedAgent, Converter={x:Static ObjectConverters.IsNotNull}}">
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<ctrl:StrokeIcon Data="{StaticResource IconFolder}" Width="14" Height="14" />
|
|
<TextBlock Text="{Binding L[desktop.agents.folder]}" />
|
|
</StackPanel>
|
|
</Button>
|
|
|
|
<Button Classes="toolbar" Command="{Binding SaveAgentsCommand}">
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<ctrl:StrokeIcon Data="{StaticResource IconSave}" Width="14" Height="14" />
|
|
<TextBlock Text="{Binding L[desktop.agents.save]}" />
|
|
</StackPanel>
|
|
</Button>
|
|
</WrapPanel>
|
|
|
|
<Border DockPanel.Dock="Top" Classes="thead">
|
|
<Grid ColumnDefinitions="1.4*,1.6*,2*">
|
|
<TextBlock Grid.Column="0" Classes="th" Text="{Binding L[desktop.agents.thDisplayName]}" />
|
|
<TextBlock Grid.Column="1" Classes="th" Text="{Binding L[desktop.agents.thModel]}" />
|
|
<TextBlock Grid.Column="2" Classes="th" Text="{Binding L[desktop.agents.thSummary]}" />
|
|
</Grid>
|
|
</Border>
|
|
|
|
<ListBox Classes="table" ItemsSource="{Binding Agents}"
|
|
SelectedItem="{Binding SelectedAgent}">
|
|
<ListBox.ItemTemplate>
|
|
<DataTemplate DataType="vm:AgentItemViewModel">
|
|
<Border Classes="tr" Padding="7">
|
|
<Grid ColumnDefinitions="1.4*,1.6*,2*">
|
|
<TextBlock Grid.Column="0" Classes="td" FontWeight="SemiBold"
|
|
Text="{Binding DisplayName}" />
|
|
<TextBlock Grid.Column="1" Classes="td dim" Text="{Binding Model}" />
|
|
<TextBlock Grid.Column="2" Classes="td dim" Text="{Binding Description}" />
|
|
</Grid>
|
|
</Border>
|
|
</DataTemplate>
|
|
</ListBox.ItemTemplate>
|
|
</ListBox>
|
|
</DockPanel>
|
|
|
|
<GridSplitter x:Name="TopSplitter" Grid.Column="1" Classes="vertical"
|
|
ResizeDirection="Columns" />
|
|
|
|
<!-- Einstellungen des gewählten Agenten -->
|
|
<ScrollViewer Grid.Column="2" VerticalScrollBarVisibility="Auto" Padding="4,0,0,0">
|
|
<ContentControl Content="{Binding SelectedAgent}">
|
|
<ContentControl.ContentTemplate>
|
|
<DataTemplate DataType="vm:AgentItemViewModel">
|
|
<StackPanel Spacing="20" MaxWidth="640" HorizontalAlignment="Left">
|
|
|
|
<StackPanel Spacing="12">
|
|
<TextBlock Classes="kicker" Text="{Binding L[desktop.agents.kickerGeneralModel]}" />
|
|
<TextBlock Classes="h2" Text="{Binding DisplayName}" />
|
|
|
|
<Grid ColumnDefinitions="*,12,*">
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.agentId]}" />
|
|
<TextBox Text="{Binding AgentId}" IsReadOnly="True" />
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2">
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.displayName]}" />
|
|
<TextBox Text="{Binding DisplayName}" />
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<Grid ColumnDefinitions="*,12,*">
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.model]}" />
|
|
<ComboBox HorizontalAlignment="Stretch"
|
|
ItemsSource="{Binding $parent[UserControl].((vm:AgentsPageViewModel)DataContext).KnownModels}"
|
|
SelectedItem="{Binding Model}" />
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2">
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.promptCaching]}" />
|
|
<ComboBox HorizontalAlignment="Stretch"
|
|
ItemsSource="{Binding $parent[UserControl].((vm:AgentsPageViewModel)DataContext).CachingOptions}"
|
|
SelectedItem="{Binding PromptCaching}" />
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<StackPanel>
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.roleDescription]}" />
|
|
<TextBox Text="{Binding Description}" AcceptsReturn="True" Height="54"
|
|
TextWrapping="Wrap" />
|
|
</StackPanel>
|
|
|
|
<StackPanel>
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.systemPrompt]}" />
|
|
<TextBox Text="{Binding SystemPrompt}" AcceptsReturn="True" Height="70"
|
|
TextWrapping="Wrap" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
|
|
<Border Classes="hr" />
|
|
|
|
<StackPanel Spacing="12">
|
|
<TextBlock Classes="kicker" Text="{Binding L[desktop.agents.kickerLimits]}" />
|
|
<TextBlock Classes="h2" Text="{Binding L[desktop.agents.limitsTitle]}" />
|
|
|
|
<Grid ColumnDefinitions="*,12,*">
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.maxSteps]}" />
|
|
<TextBox Text="{Binding MaxSteps}" />
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2">
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.timeoutSeconds]}" />
|
|
<TextBox Text="{Binding TimeoutSeconds}" />
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<Grid ColumnDefinitions="*,12,*">
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.maxContextTokens]}" />
|
|
<TextBox Text="{Binding MaxContextTokens}" />
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2">
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.maxToolResultChars]}" />
|
|
<TextBox Text="{Binding MaxToolResultChars}" />
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<Grid ColumnDefinitions="*,12,*">
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.dailyCost]}" />
|
|
<TextBox Text="{Binding DailyCostUsd}" />
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2">
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.dailyTokens]}" />
|
|
<TextBox Text="{Binding DailyTokens}" />
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<StackPanel>
|
|
<TextBlock Classes="label" Text="{Binding L[desktop.agents.whenExhausted]}" />
|
|
<ComboBox HorizontalAlignment="Stretch"
|
|
ItemsSource="{Binding WhenExhaustedOptions}"
|
|
SelectedItem="{Binding WhenExhausted}" />
|
|
<TextBlock Classes="caption" TextWrapping="Wrap"
|
|
Text="{Binding L[desktop.agents.whenExhaustedHint]}" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
|
|
</StackPanel>
|
|
</DataTemplate>
|
|
</ContentControl.ContentTemplate>
|
|
</ContentControl>
|
|
</ScrollViewer>
|
|
</Grid>
|
|
|
|
<GridSplitter x:Name="VerticalSplitter" Grid.Row="1" Classes="horizontal"
|
|
ResizeDirection="Rows" Margin="0,8" />
|
|
|
|
<!-- ══════════════════ Unten: Werkzeuge ══════════════════ -->
|
|
<Grid x:Name="BottomGrid" Grid.Row="2" ColumnDefinitions="0.44*,Auto,0.56*">
|
|
|
|
<DockPanel Grid.Column="0" Margin="0,0,14,0">
|
|
<TextBlock DockPanel.Dock="Top" Classes="kicker" Margin="0,4,0,8"
|
|
Text="{Binding AllowedToolsHeader}" />
|
|
|
|
<Border DockPanel.Dock="Top" Classes="thead">
|
|
<Grid ColumnDefinitions="36,1.4*,2.4*">
|
|
<TextBlock Grid.Column="1" Classes="th" Text="{Binding L[desktop.agents.thTool]}" />
|
|
<TextBlock Grid.Column="2" Classes="th" Text="{Binding L[desktop.agents.thDescription]}" />
|
|
</Grid>
|
|
</Border>
|
|
|
|
<ListBox Classes="table" ItemsSource="{Binding SelectedAgent.AvailableTools}"
|
|
SelectedItem="{Binding SelectedTool}">
|
|
<ListBox.ItemTemplate>
|
|
<DataTemplate DataType="vm:ToolItemViewModel">
|
|
<Border Classes="tr" Padding="7">
|
|
<Grid ColumnDefinitions="36,1.4*,2.4*">
|
|
<CheckBox Grid.Column="0" IsChecked="{Binding IsEnabled}"
|
|
VerticalAlignment="Center" />
|
|
<TextBlock Grid.Column="1" Classes="td" FontWeight="SemiBold"
|
|
Text="{Binding Name}" />
|
|
<TextBlock Grid.Column="2" Classes="td dim" Text="{Binding Description}" />
|
|
</Grid>
|
|
</Border>
|
|
</DataTemplate>
|
|
</ListBox.ItemTemplate>
|
|
</ListBox>
|
|
</DockPanel>
|
|
|
|
<GridSplitter x:Name="BottomSplitter" Grid.Column="1" Classes="vertical"
|
|
ResizeDirection="Columns" />
|
|
|
|
<DockPanel Grid.Column="2" Margin="4,0,0,0">
|
|
<StackPanel DockPanel.Dock="Top" Spacing="2" Margin="0,4,0,10">
|
|
<TextBlock Classes="kicker" Text="{Binding L[desktop.agents.toolSettingsKicker]}" />
|
|
<DockPanel>
|
|
<TextBlock Classes="h2" VerticalAlignment="Center"
|
|
Text="{Binding SelectedTool.Name}" />
|
|
<Button DockPanel.Dock="Right" HorizontalAlignment="Right" Classes="toolbar primary"
|
|
Command="{Binding SaveToolSettingsCommand}"
|
|
IsEnabled="{Binding ToolSettings, Converter={x:Static ObjectConverters.IsNotNull}}">
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<ctrl:StrokeIcon Data="{StaticResource IconSave}" Width="14" Height="14" />
|
|
<TextBlock Text="{Binding L[desktop.agents.apply]}" />
|
|
</StackPanel>
|
|
</Button>
|
|
</DockPanel>
|
|
</StackPanel>
|
|
|
|
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
|
<ContentControl Content="{Binding ToolSettings}" />
|
|
</ScrollViewer>
|
|
</DockPanel>
|
|
</Grid>
|
|
|
|
</Grid>
|
|
</DockPanel>
|
|
|
|
</UserControl>
|