Initial commit: ClawdDotNet
Import des bestehenden Projektstands in Git. - .NET 10 WinForms Anwendung (Multi-Agent / Tool-System) - .gitignore fuer Build-Artefakte, Secrets und Runtime-Daten ergaenzt Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ClawdDotNet.Core.Config;
|
||||
|
||||
public sealed class AgentConfig
|
||||
{
|
||||
[JsonPropertyName("agentId")]
|
||||
public string AgentId { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("displayName")]
|
||||
public string DisplayName { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("model")]
|
||||
public string Model { get; set; } = "anthropic/claude-sonnet-4-5";
|
||||
|
||||
[JsonPropertyName("systemPrompt")]
|
||||
public string SystemPrompt { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Identität des Agenten (aus Identity.md geladen).
|
||||
/// Definiert WER der Agent ist: Name, Rolle, Hintergrund.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string Identity { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Seele des Agenten (aus Soul.md geladen).
|
||||
/// Definiert WIE der Agent denkt: Persönlichkeit, Werte, Verhaltensmuster.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string Soul { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Lokaler Pfad zum Workspace-Verzeichnis des Agenten.
|
||||
/// Wird zur Laufzeit vom Host gesetzt.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Kurzbeschreibung der Rolle/Aufgabe des Agenten.
|
||||
/// Wird aus AgentList.json geladen und bei list_agents angezeigt.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string Description { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Absoluter Pfad zum Agent-Verzeichnis (Agent-XYZ).
|
||||
/// Wird zur Laufzeit gesetzt und bleibt stabil auch bei DisplayName-Änderungen.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string AgentDir { get; set; } = "";
|
||||
|
||||
[JsonIgnore]
|
||||
public string WorkspacePath { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Lokaler Pfad zum geteilten Workspace-Verzeichnis (SharedWorkspace).
|
||||
/// Wird zur Laufzeit vom Host gesetzt.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string SharedWorkspacePath { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Baut den vollständigen System-Prompt aus Identity + Soul + SystemPrompt zusammen.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string FullSystemPrompt
|
||||
{
|
||||
get
|
||||
{
|
||||
var parts = new List<string>();
|
||||
if (!string.IsNullOrWhiteSpace(Identity))
|
||||
parts.Add($"# Identity\n{Identity}");
|
||||
if (!string.IsNullOrWhiteSpace(Soul))
|
||||
parts.Add($"# Soul\n{Soul}");
|
||||
if (!string.IsNullOrWhiteSpace(SystemPrompt))
|
||||
parts.Add(SystemPrompt);
|
||||
return string.Join("\n\n", parts);
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("tools")]
|
||||
public Dictionary<string, Dictionary<string, object?>> Tools { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("scheduler")]
|
||||
public SchedulerConfig? Scheduler { get; set; }
|
||||
|
||||
[JsonPropertyName("toolJobs")]
|
||||
public List<ToolJobConfig> ToolJobs { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("loopGuard")]
|
||||
public LoopGuardConfig LoopGuard { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class SchedulerConfig
|
||||
{
|
||||
[JsonPropertyName("cron")]
|
||||
public string Cron { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("runOnStart")]
|
||||
public bool RunOnStart { get; set; }
|
||||
|
||||
[JsonPropertyName("taskMessage")]
|
||||
public string TaskMessage { get; set; } = "Führe deine zugewiesenen Aufgaben aus.";
|
||||
}
|
||||
|
||||
public sealed class LoopGuardConfig
|
||||
{
|
||||
[JsonPropertyName("maxSteps")]
|
||||
public int MaxSteps { get; set; } = 20;
|
||||
|
||||
[JsonPropertyName("maxTokens")]
|
||||
public int MaxTokens { get; set; } = 80_000;
|
||||
|
||||
[JsonPropertyName("timeoutSeconds")]
|
||||
public int TimeoutSeconds { get; set; } = 600;
|
||||
|
||||
[JsonPropertyName("maxContextTokens")]
|
||||
public int MaxContextTokens { get; set; } = 100_000;
|
||||
|
||||
[JsonPropertyName("compactionThreshold")]
|
||||
public double CompactionThreshold { get; set; } = 0.80;
|
||||
|
||||
[JsonIgnore]
|
||||
public TimeSpan Timeout => TimeSpan.FromSeconds(TimeoutSeconds);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ClawdDotNet.Core.Config;
|
||||
|
||||
public static class ConfigLoader
|
||||
{
|
||||
private static readonly JsonSerializerOptions JsonOptions = new()
|
||||
{
|
||||
ReadCommentHandling = JsonCommentHandling.Skip,
|
||||
AllowTrailingCommas = true,
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
public static async Task<InstanceConfig> LoadAsync(string filePath, CancellationToken ct = default)
|
||||
{
|
||||
if (!File.Exists(filePath))
|
||||
throw new FileNotFoundException($"Config file not found: {filePath}");
|
||||
|
||||
await using var stream = File.OpenRead(filePath);
|
||||
var config = await JsonSerializer.DeserializeAsync<InstanceConfig>(stream, JsonOptions, ct)
|
||||
?? throw new InvalidOperationException($"Config file is empty or invalid: {filePath}");
|
||||
|
||||
Validate(config, filePath);
|
||||
return config;
|
||||
}
|
||||
|
||||
private static void Validate(InstanceConfig config, string filePath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(config.OpenRouterApiKey))
|
||||
throw new InvalidOperationException($"'openRouterApiKey' is required in {filePath}");
|
||||
|
||||
var agentIds = new HashSet<string>();
|
||||
foreach (var agent in config.Agents)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(agent.AgentId))
|
||||
throw new InvalidOperationException($"Every agent must have an 'agentId' in {filePath}");
|
||||
|
||||
if (!agentIds.Add(agent.AgentId))
|
||||
throw new InvalidOperationException($"Duplicate agentId '{agent.AgentId}' in {filePath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ClawdDotNet.Core.Config;
|
||||
|
||||
public sealed class InstanceConfig
|
||||
{
|
||||
[JsonPropertyName("instanceId")]
|
||||
public string InstanceId { get; set; } = Guid.NewGuid().ToString("N")[..8];
|
||||
|
||||
[JsonPropertyName("instanceName")]
|
||||
public string InstanceName { get; set; } = "Default";
|
||||
|
||||
[JsonPropertyName("openRouterApiKey")]
|
||||
public string OpenRouterApiKey { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("workingDirectory")]
|
||||
public string WorkingDirectory { get; set; } = "./data/";
|
||||
|
||||
[JsonPropertyName("logDirectory")]
|
||||
public string LogDirectory { get; set; } = "./Logs";
|
||||
|
||||
[JsonPropertyName("webServerPort")]
|
||||
public int WebServerPort { get; set; } = 8080;
|
||||
|
||||
[JsonPropertyName("telegramClient")]
|
||||
public TelegramClientConfig? TelegramClient { get; set; }
|
||||
|
||||
[JsonPropertyName("agents")]
|
||||
public List<AgentConfig> Agents { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("services")]
|
||||
public List<ServiceConfig> Services { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class TelegramClientConfig
|
||||
{
|
||||
[JsonPropertyName("apiId")]
|
||||
public int ApiId { get; set; }
|
||||
|
||||
[JsonPropertyName("apiHash")]
|
||||
public string ApiHash { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("phoneNumber")]
|
||||
public string PhoneNumber { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("password2FA")]
|
||||
public string? Password2FA { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ClawdDotNet.Core.Config;
|
||||
|
||||
public sealed class ServiceConfig
|
||||
{
|
||||
[JsonPropertyName("serviceId")]
|
||||
public string ServiceId { get; set; } = Guid.NewGuid().ToString("N")[..8];
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("type")]
|
||||
public string Type { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
[JsonPropertyName("enabled")]
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("autoStart")]
|
||||
public bool AutoStart { get; set; }
|
||||
|
||||
[JsonPropertyName("description")]
|
||||
public string Description { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("builtIn")]
|
||||
public bool BuiltIn { get; set; }
|
||||
}
|
||||
|
||||
public static class BuiltInServices
|
||||
{
|
||||
public const string AgentChatWebUI = "AgentChatWebUI";
|
||||
public const string AgentWebsite = "AgentWebsite";
|
||||
public const string ClawdDotNetApi = "ClawdDotNetApi";
|
||||
|
||||
public static List<ServiceConfig> CreateDefaults() =>
|
||||
[
|
||||
new()
|
||||
{
|
||||
ServiceId = "svc_chat",
|
||||
Name = "Agent Chat WebUI",
|
||||
Type = AgentChatWebUI,
|
||||
Port = 5080,
|
||||
Enabled = true,
|
||||
AutoStart = true,
|
||||
BuiltIn = true,
|
||||
Description = "WebUI für den Agenten-Chat (WebView2)"
|
||||
},
|
||||
new()
|
||||
{
|
||||
ServiceId = "svc_web",
|
||||
Name = "Agent Website",
|
||||
Type = AgentWebsite,
|
||||
Port = 5081,
|
||||
Enabled = false,
|
||||
AutoStart = false,
|
||||
BuiltIn = true,
|
||||
Description = "Von Agenten entwickelte und betreute Website"
|
||||
},
|
||||
new()
|
||||
{
|
||||
ServiceId = "svc_api",
|
||||
Name = "ClawdDotNet API",
|
||||
Type = ClawdDotNetApi,
|
||||
Port = 5082,
|
||||
Enabled = true,
|
||||
AutoStart = true,
|
||||
BuiltIn = true,
|
||||
Description = "REST-API für die Kommunikation mit der WebApp"
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ClawdDotNet.Core.Config;
|
||||
|
||||
public sealed class ToolJobConfig
|
||||
{
|
||||
[JsonPropertyName("jobId")]
|
||||
public string JobId { get; set; } = Guid.NewGuid().ToString("N")[..8];
|
||||
|
||||
[JsonPropertyName("toolName")]
|
||||
public string ToolName { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("jobTypeId")]
|
||||
public string JobTypeId { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("cron")]
|
||||
public string Cron { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("enabled")]
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("runOnStart")]
|
||||
public bool RunOnStart { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user