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:
+247
@@ -0,0 +1,247 @@
|
||||
using ClawdDotNet.Core.Api;
|
||||
using ClawdDotNet.Core.Config;
|
||||
using ClawdDotNet.Core.Engine;
|
||||
using ClawdDotNet.Core.Logging;
|
||||
using ClawdDotNet.Core.Security;
|
||||
using ClawdDotNet.Core.Scheduling;
|
||||
using ClawdDotNet.Core.Tools;
|
||||
using ClawdDotNet.Core.State;
|
||||
using ClawdDotNet.Services;
|
||||
using ClawdDotNet.Tools.FileRW;
|
||||
using ClawdDotNet.Tools.Telegram;
|
||||
using ClawdDotNet.Tools.Mail;
|
||||
using ClawdDotNet.Tools.Database;
|
||||
using ClawdDotNet.Tools.FTP;
|
||||
using ClawdDotNet.Tools.DirectAPI;
|
||||
using ClawdDotNet.Tools.WebFetch;
|
||||
using ClawdDotNet.Tools.WebMonitor;
|
||||
using ClawdDotNet.Tools.AgentComm;
|
||||
using ClawdDotNet.Tools.AgentSpawn;
|
||||
using ClawdDotNet.Tools.SocialMediaManager;
|
||||
using ClawdDotNet.Tools.AgentEditor;
|
||||
using ClawdDotNet.Tools.TelegramClient;
|
||||
using ClawdDotNet.UI;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace ClawdDotNet;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
ApplicationConfiguration.Initialize();
|
||||
|
||||
// ─── 0. Embedded UI extrahieren ───
|
||||
EmbeddedUiManager.ExtractToTemp();
|
||||
|
||||
// ─── 1. App-Settings laden ───
|
||||
var settingsManager = new SettingsManager();
|
||||
settingsManager.Load();
|
||||
var appSettings = settingsManager.AppSettings;
|
||||
|
||||
// ─── 2. InstanceDirectoryManager erstellen ───
|
||||
var instancesDir = Path.GetFullPath(appSettings.InstancesDirectory);
|
||||
var dirManager = new InstanceDirectoryManager(instancesDir);
|
||||
|
||||
// ─── 3. Instanz-Verzeichnis auswählen ───
|
||||
string instancePath;
|
||||
|
||||
#if DEBUG
|
||||
// Im Debug-Modus: Dev-Instanz automatisch erstellen/starten
|
||||
const string devInstanceName = "Dev";
|
||||
instancePath = dirManager.GetInstancePath(devInstanceName);
|
||||
|
||||
if (!Directory.Exists(instancePath))
|
||||
{
|
||||
dirManager.CreateInstance(devInstanceName);
|
||||
}
|
||||
#else
|
||||
// Im Release-Modus: InstanceManager anzeigen
|
||||
var instanceManager = new frm_InstanceManager(dirManager, settingsManager);
|
||||
var dialogResult = instanceManager.ShowDialog();
|
||||
|
||||
if (dialogResult != DialogResult.OK || string.IsNullOrWhiteSpace(instanceManager.SelectedInstancePath))
|
||||
{
|
||||
return; // Benutzer hat abgebrochen
|
||||
}
|
||||
|
||||
instancePath = instanceManager.SelectedInstancePath;
|
||||
instanceManager.Dispose();
|
||||
#endif
|
||||
|
||||
// ─── 4. Instanz-Config aus Verzeichnisstruktur laden ───
|
||||
InstanceConfig instanceConfig;
|
||||
try
|
||||
{
|
||||
instanceConfig = dirManager.LoadInstanceConfig(instancePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(
|
||||
$"Fehler beim Laden der Instanz:\n{instancePath}\n\n{ex.Message}",
|
||||
"ClawdDotNet – Fehler",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
// ─── 5. Logging-System initialisieren ───
|
||||
var logDir = Path.GetFullPath(
|
||||
!string.IsNullOrWhiteSpace(instanceConfig.LogDirectory)
|
||||
? instanceConfig.LogDirectory
|
||||
: appSettings.LogDirectory);
|
||||
|
||||
var minLevel = Enum.TryParse<ClawdDotNet.Core.Logging.LogLevel>(
|
||||
appSettings.MinimumLogLevel, true, out var ml)
|
||||
? ml
|
||||
: ClawdDotNet.Core.Logging.LogLevel.Info;
|
||||
|
||||
var loggerFactory = LoggingExtensions.CreateClawdLoggerFactory(logDir, minLevel);
|
||||
var coreLogger = loggerFactory.CreateLogger("ClawdDotNet.Core.Startup");
|
||||
|
||||
coreLogger.LogInformation("ClawdDotNet startet – Instanz: {Instance} ({Id})",
|
||||
instanceConfig.InstanceName, instanceConfig.InstanceId);
|
||||
coreLogger.LogInformation("Instanz-Verzeichnis: {Path}", instancePath);
|
||||
|
||||
// ─── 6. Core-Komponenten erzeugen ───
|
||||
var toolRegistry = new ToolRegistry();
|
||||
toolRegistry.Register(new FileRWTool());
|
||||
toolRegistry.Register(new TelegramTool());
|
||||
toolRegistry.Register(new MailTool());
|
||||
toolRegistry.Register(new DatabaseTool());
|
||||
toolRegistry.Register(new FTPTool());
|
||||
toolRegistry.Register(new DirectApiTool());
|
||||
toolRegistry.Register(new WebFetchTool());
|
||||
toolRegistry.Register(new WebMonitorTool());
|
||||
toolRegistry.Register(new AgentCommTool());
|
||||
toolRegistry.Register(new SocialMediaManagerTool());
|
||||
toolRegistry.Register(new AgentSpawnTool());
|
||||
toolRegistry.Register(new AgentEditorTool());
|
||||
|
||||
// ─── 6a. TelegramClient (MTProto User-API) ───
|
||||
TelegramClientManager? tgClientManager = null;
|
||||
if (instanceConfig.TelegramClient is not null)
|
||||
{
|
||||
tgClientManager = new TelegramClientManager(
|
||||
instanceConfig,
|
||||
instancePath,
|
||||
loggerFactory.CreateLogger("ClawdDotNet.Tools.TelegramClient"));
|
||||
toolRegistry.Register(new TelegramClientTool(tgClientManager));
|
||||
coreLogger.LogInformation("TelegramClient-Tool registriert");
|
||||
}
|
||||
|
||||
var permissionGate = new PermissionGate();
|
||||
|
||||
// TODO: Tools aus tools/ Ordner laden
|
||||
// foreach (var toolDll in Directory.GetFiles("./tools", "*.dll"))
|
||||
// LoadToolPlugin(toolDll, toolRegistry);
|
||||
|
||||
OpenRouterClient? openRouterClient = null;
|
||||
AgentEngine? agentEngine = null;
|
||||
AgentScheduler? agentScheduler = null;
|
||||
ToolJobScheduler? toolJobScheduler = null;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(instanceConfig.OpenRouterApiKey))
|
||||
{
|
||||
openRouterClient = new OpenRouterClient(
|
||||
instanceConfig.OpenRouterApiKey,
|
||||
loggerFactory.CreateLogger("ClawdDotNet.Core.Api.OpenRouterClient"));
|
||||
|
||||
// ModelTypeConverter mit dem Client verbinden für PropertyGrid-Dropdown
|
||||
ClawdDotNet.Models.ModelTypeConverter.Client = openRouterClient;
|
||||
|
||||
// ─── 6.1. StateStore initialisieren ───
|
||||
var stateDbPath = Path.Combine(instancePath, "state.db");
|
||||
var stateStore = new SqliteStateStore(stateDbPath);
|
||||
|
||||
agentEngine = new AgentEngine(openRouterClient, toolRegistry, permissionGate, stateStore, loggerFactory);
|
||||
agentEngine.SetAgentConfigProvider(
|
||||
() => instanceConfig.Agents,
|
||||
instanceConfig.InstanceId,
|
||||
agentId =>
|
||||
{
|
||||
var agent = instanceConfig.Agents.FirstOrDefault(a => a.AgentId == agentId);
|
||||
if (agent is null) return null;
|
||||
return string.IsNullOrWhiteSpace(agent.AgentDir) ? null : agent.AgentDir;
|
||||
});
|
||||
agentEngine.LoadPersistedChats();
|
||||
agentScheduler = new AgentScheduler(agentEngine, instanceConfig.InstanceId, loggerFactory);
|
||||
agentScheduler.RegisterAll(instanceConfig.Agents);
|
||||
|
||||
toolJobScheduler = new ToolJobScheduler(agentEngine, toolRegistry, stateStore, loggerFactory, instanceConfig.InstanceId);
|
||||
toolJobScheduler.RegisterAll(instanceConfig.Agents);
|
||||
|
||||
coreLogger.LogInformation("AgentEngine und Scheduler erstellt, Chat-Verläufe geladen");
|
||||
}
|
||||
else
|
||||
{
|
||||
coreLogger.LogWarning("Kein OpenRouter API-Key konfiguriert – Agenten sind deaktiviert");
|
||||
}
|
||||
|
||||
// ─── 6b. TelegramClient verbinden (Session oder interaktiver Login) ───
|
||||
if (tgClientManager is not null)
|
||||
{
|
||||
tgClientManager.OnLoginCodeRequired += async (prompt) =>
|
||||
{
|
||||
string? code = null;
|
||||
await Task.Run(() =>
|
||||
{
|
||||
code = Microsoft.VisualBasic.Interaction.InputBox(
|
||||
prompt, "Telegram Verifizierung", "");
|
||||
});
|
||||
return code ?? "";
|
||||
};
|
||||
|
||||
tgClientManager.On2FAPasswordRequired += async () =>
|
||||
{
|
||||
string? pw = null;
|
||||
await Task.Run(() =>
|
||||
{
|
||||
pw = Microsoft.VisualBasic.Interaction.InputBox(
|
||||
"Bitte 2FA-Passwort eingeben:", "Telegram 2FA", "");
|
||||
});
|
||||
return pw ?? "";
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
tgClientManager.ConnectAsync(CancellationToken.None)
|
||||
.GetAwaiter().GetResult();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
coreLogger.LogError(ex, "Telegram: Login fehlgeschlagen");
|
||||
}
|
||||
}
|
||||
|
||||
// ─── 7. MainForm starten ───
|
||||
var form = new frm_main(
|
||||
settingsManager,
|
||||
instanceConfig,
|
||||
instancePath,
|
||||
logDir,
|
||||
loggerFactory,
|
||||
toolRegistry,
|
||||
dirManager,
|
||||
agentEngine,
|
||||
agentScheduler,
|
||||
toolJobScheduler);
|
||||
|
||||
Application.Run(form);
|
||||
|
||||
// ─── 8. Aufräumen ───
|
||||
coreLogger.LogInformation("ClawdDotNet wird beendet");
|
||||
|
||||
if (toolJobScheduler is not null)
|
||||
toolJobScheduler.DisposeAsync().AsTask().GetAwaiter().GetResult();
|
||||
|
||||
if (agentScheduler is not null)
|
||||
agentScheduler.DisposeAsync().AsTask().GetAwaiter().GetResult();
|
||||
|
||||
if (tgClientManager is not null)
|
||||
tgClientManager.DisposeAsync().AsTask().GetAwaiter().GetResult();
|
||||
|
||||
openRouterClient?.Dispose();
|
||||
loggerFactory.Dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user