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>
248 lines
9.2 KiB
C#
248 lines
9.2 KiB
C#
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();
|
||
}
|
||
}
|