feat(ui): complete Avalonia UI port with 7 main pages, tool settings & top MenuBar

This commit is contained in:
Richard
2026-08-10 10:48:34 +02:00
parent a0e18d2a57
commit b5bf97ae74
187 changed files with 20054 additions and 882 deletions
@@ -188,6 +188,14 @@ public sealed class LoopGuardConfig
[JsonPropertyName("maxContextTokens")]
public int MaxContextTokens { get; set; } = 100_000;
/// <summary>
/// Obergrenze für die Ausgabe eines einzelnen Schritts (<c>max_tokens</c> im Request).
/// Deckelt die teuerste Token-Art gegen Ausreißer (B11/T8). 0 = keine Angabe, dann gilt
/// der Standard des Anbieters.
/// </summary>
[JsonPropertyName("maxResponseTokens")]
public int MaxResponseTokens { get; set; } = 8_192;
[JsonPropertyName("compactionThreshold")]
public double CompactionThreshold { get; set; } = 0.80;
@@ -25,6 +25,10 @@ public sealed class InstanceConfig
[JsonPropertyName("telegramClient")]
public TelegramClientConfig? TelegramClient { get; set; }
/// <summary>Anbindung an das Watchdog-Modul des Deploymentcenters (Instanz-Heartbeat).</summary>
[JsonPropertyName("watchdog")]
public WatchdogConfig Watchdog { get; set; } = new();
/// <summary>Tagesgrenzen über alle Agenten der Instanz hinweg. 0 = keine Grenze.</summary>
[JsonPropertyName("budget")]
public InstanceBudget Budget { get; set; } = new();
@@ -34,6 +34,7 @@ public static class BuiltInServices
public const string AgentChatWebUI = "AgentChatWebUI";
public const string AgentWebsite = "AgentWebsite";
public const string ClawdDotNetApi = "ClawdDotNetApi";
public const string InstanceWatchdog = "InstanceWatchdog";
public static List<ServiceConfig> CreateDefaults() =>
[
@@ -69,6 +70,17 @@ public static class BuiltInServices
AutoStart = true,
BuiltIn = true,
Description = "REST-API für die Kommunikation mit der WebApp"
},
new()
{
ServiceId = "svc_watchdog",
Name = "Instanz-Watchdog",
Type = InstanceWatchdog,
Port = 0,
Enabled = false,
AutoStart = true,
BuiltIn = true,
Description = "Sendet Heartbeats ans Deploymentcenter (URL/Token in den Anwendungseinstellungen)"
}
];
}
@@ -0,0 +1,60 @@
using System.Text.Json.Serialization;
namespace ClawdDotNet.Core.Config;
/// <summary>
/// Pro-Instanz-Teil der Watchdog-Anbindung ans Deploymentcenter.
///
/// <para><b>Ein Monitor je Instanz.</b> Der Monitor wird serverseitig über das Paar
/// <c>source</c> + <c>instance</c> geführt. Alle Instanzen melden unter derselben
/// <see cref="Source"/> und tragen ihre eigene <see cref="Instance"/> — damit hat jede
/// laufende Instanz einen eigenen Zustand, ein eigenes Intervall und einen eigenen
/// Metrik-Verlauf. Fällt eine von dreien aus, fällt genau deren Monitor.</para>
///
/// <para>Server-URL und das anwendungsweite Token liegen in den Anwendungseinstellungen.
/// Beim ersten Start tauscht die Instanz das Token gegen ein eigenes, eingeschränktes
/// Sub-Token (<c>/api/tokens/v1/provision</c>) und legt es hier verschlüsselt ab —
/// danach liegt auf der Instanz nicht mehr das Master-Token.</para>
///
/// <para>Ein/Aus läuft über den eingebauten Dienst <c>InstanceWatchdog</c>.</para>
/// </summary>
public sealed class WatchdogConfig
{
/// <summary>Dienst-Kennung im Deploymentcenter. Alle Instanzen teilen sich dieselbe Source.</summary>
[JsonPropertyName("source")]
public string Source { get; set; } = "clawddotnet";
/// <summary>
/// Name dieser Instanz im Monitor. Leer bedeutet: die <c>InstanceId</c> wird
/// verwendet — stabil, aber im Dashboard nichtssagend. Wer lesbare Namen möchte,
/// trägt hier einen ein; ein späterer Wechsel legt allerdings einen neuen Monitor an.
/// </summary>
[JsonPropertyName("instance")]
public string Instance { get; set; } = "";
/// <summary>Gruppierung im Dashboard (reine Anzeige, keine Hierarchie).</summary>
[JsonPropertyName("group")]
public string Group { get; set; } = "ClawdDotNet";
/// <summary>
/// Sende-Takt in Sekunden. Daraus leitet der Evaluator die Schwellen ab:
/// nach dem Doppelten <c>warning</c>, nach dem Vierfachen <c>down</c>.
/// </summary>
[JsonPropertyName("intervalSeconds")]
public int IntervalSeconds { get; set; } = 60;
/// <summary>
/// Das für diese Instanz ausgestellte Sub-Token. Wird automatisch gesetzt und
/// verschlüsselt gespeichert.
/// </summary>
[JsonPropertyName("agentToken")]
public string AgentToken { get; set; } = "";
/// <summary>True, sobald ein eigenes Token vorliegt.</summary>
[JsonIgnore]
public bool HasToken => !string.IsNullOrWhiteSpace(AgentToken);
/// <summary>Der Wert, der als <c>instance</c> gemeldet wird.</summary>
public string ResolveInstance(string instanceId) =>
string.IsNullOrWhiteSpace(Instance) ? instanceId : Instance.Trim();
}