Stufe 1 (#764): Werkzeugeinstellungen, Sicherungszeitplan und Import als neue Instanz

- Werkzeugformulare aus den typisierten Einstellungsklassen (L8): Geheimnisse
  nur schreibend, nur geaenderte Schluessel werden ersetzt, Rechte bleiben
- Database.allowedTables las ein JSON-Array als rohen Text und haette es beim
  naechsten Speichern zerlegt
- Automatische Sicherung der Instanz in der Sicherungsansicht (L10)
- Sicherung hochladen und als neue Instanz einspielen (L11): Pfade der alten
  Maschine werden zurueckgesetzt, eine Kopie neben dem Original bekommt eine
  eigene ID, Autostart aus; Upload bis 4 GB
- api.js schickte eine Datei als "{}"; Dialoge schliessen beim Seitenwechsel

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-10-02 14:13:37 +02:00
co-authored by Claude Opus 5.5
parent 8552755bb6
commit d2559c763a
17 changed files with 1027 additions and 28 deletions
@@ -488,6 +488,33 @@ public sealed class AgentAdministration(AppHost host)
$"Prompt history default: {Core.Transcripts.PromptHistorySettings.Describe(retentionDays)}.");
}
/// <summary>
/// #764: The settings form of a tool for one agent (<see cref="ToolSettingsForms"/>) —
/// also for a tool the agent does not have yet, so one can see what there is to set.
/// </summary>
public IReadOnlyList<ToolSettingField>? ToolSettingsForm(string agentId, string toolName)
=> Find(agentId) is { } agent
? ToolSettingsForms.Describe(toolName, agent.Tools.GetValueOrDefault(toolName) ?? new Dictionary<string, object?>())
: null;
/// <summary>
/// #764: Writes form input from the WebUI into a tool's settings. Secrets left empty keep
/// their value, keys the form does not know are kept, and the rights stay (see
/// <see cref="SetToolSettings"/>).
/// </summary>
public AdminResult ApplyToolSettingsForm(string agentId, string toolName, IReadOnlyDictionary<string, string?> input)
{
if (Find(agentId) is not { } agent)
return AdminResult.Failure($"No agent with id '{agentId}'.");
var current = agent.Tools.GetValueOrDefault(toolName) ?? new Dictionary<string, object?>();
var (settings, error) = ToolSettingsForms.Apply(toolName, current, input);
return settings is null
? AdminResult.Failure(error ?? "Not saved.")
: SetToolSettings(agentId, toolName, settings);
}
public AdminResult SetToolSettings(
string agentId, string toolName, Dictionary<string, object?> settings)
{