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>
166 lines
5.2 KiB
C#
166 lines
5.2 KiB
C#
using ClawdDotNet.Core.Config;
|
||
using ClawdDotNet.Core.Engine;
|
||
using ClawdDotNet.UI;
|
||
using Microsoft.Extensions.Logging;
|
||
using Microsoft.Web.WebView2.Core;
|
||
|
||
namespace ClawdDotNet;
|
||
|
||
public partial class frm_chat : Form
|
||
{
|
||
private readonly AgentConfig _agentConfig;
|
||
private readonly AgentEngine _engine;
|
||
private readonly string _instanceId;
|
||
private readonly ILogger _logger;
|
||
|
||
private WebViewBridge? _bridge;
|
||
|
||
public frm_chat(AgentConfig agentConfig, AgentEngine engine,
|
||
string instanceId, ILoggerFactory loggerFactory)
|
||
{
|
||
_agentConfig = agentConfig;
|
||
_engine = engine;
|
||
_instanceId = instanceId;
|
||
_logger = loggerFactory.CreateLogger($"ClawdDotNet.UI.Chat.{agentConfig.AgentId}");
|
||
|
||
InitializeComponent();
|
||
Text = $"Chat – {agentConfig.DisplayName}";
|
||
Load += async (_, _) => await InitWebViewAsync();
|
||
}
|
||
|
||
public frm_chat()
|
||
{
|
||
_agentConfig = new AgentConfig();
|
||
_engine = null!;
|
||
_instanceId = "";
|
||
_logger = LoggerFactory.Create(_ => { }).CreateLogger("Design");
|
||
InitializeComponent();
|
||
}
|
||
|
||
private async Task InitWebViewAsync()
|
||
{
|
||
try
|
||
{
|
||
await webView_chat2.EnsureCoreWebView2Async();
|
||
|
||
var uiPath = EmbeddedUiManager.GetExtractedPath();
|
||
webView_chat2.CoreWebView2.SetVirtualHostNameToFolderMapping(
|
||
"ui.clwd.internal", uiPath,
|
||
CoreWebView2HostResourceAccessKind.DenyCors);
|
||
|
||
_bridge = new WebViewBridge(webView_chat2, _logger);
|
||
_bridge.MessageReceived += OnBridgeMessage;
|
||
|
||
webView_chat2.CoreWebView2.Navigate(
|
||
$"https://ui.clwd.internal/chat.html?agent={_agentConfig.AgentId}");
|
||
|
||
await Task.Delay(500);
|
||
|
||
await _bridge.SendAsync(new BridgeMessage(
|
||
Type: BridgeTypes.AgentListUpdate,
|
||
AgentId: _agentConfig.AgentId,
|
||
Extra: new
|
||
{
|
||
agents = new[]
|
||
{
|
||
new
|
||
{
|
||
agentId = _agentConfig.AgentId,
|
||
displayName = _agentConfig.DisplayName,
|
||
model = _agentConfig.Model
|
||
}
|
||
}
|
||
}));
|
||
|
||
await LoadChatHistoryAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "frm_chat WebView2 init failed");
|
||
}
|
||
}
|
||
|
||
private async void OnBridgeMessage(BridgeMessage msg)
|
||
{
|
||
if (InvokeRequired) { Invoke(() => OnBridgeMessage(msg)); return; }
|
||
|
||
switch (msg.Type)
|
||
{
|
||
case BridgeTypes.UserMessage:
|
||
if (msg.Content is not null)
|
||
await HandleUserMessageAsync(msg.Content);
|
||
break;
|
||
|
||
case BridgeTypes.RunNow:
|
||
await HandleUserMessageAsync("Führe deine zugewiesenen Aufgaben aus.");
|
||
break;
|
||
|
||
case BridgeTypes.AbortRun:
|
||
_engine.AbortChat(_agentConfig.AgentId);
|
||
break;
|
||
}
|
||
}
|
||
|
||
private async Task HandleUserMessageAsync(string text)
|
||
{
|
||
if (_bridge is null) return;
|
||
|
||
await _bridge.SendAsync(new BridgeMessage(
|
||
Type: BridgeTypes.ChatMessage,
|
||
AgentId: _agentConfig.AgentId,
|
||
Content: text,
|
||
Extra: new { role = "user", timestamp = DateTime.Now }));
|
||
|
||
await _bridge.SendAsync(new BridgeMessage(
|
||
Type: BridgeTypes.ChatTyping,
|
||
AgentId: _agentConfig.AgentId));
|
||
|
||
_ = Task.Run(async () =>
|
||
{
|
||
try
|
||
{
|
||
var result = await _engine.ChatAsync(
|
||
_agentConfig, text, _instanceId, CancellationToken.None,
|
||
source: ChatSource.WebView);
|
||
|
||
await _bridge.SendAsync(new BridgeMessage(
|
||
Type: BridgeTypes.ChatMessage,
|
||
AgentId: _agentConfig.AgentId,
|
||
Content: result.FinalMessage ?? "[Keine Antwort]",
|
||
Extra: new { role = "assistant", timestamp = DateTime.Now }));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "Chat failed");
|
||
await _bridge!.SendAsync(new BridgeMessage(
|
||
Type: BridgeTypes.ChatMessage,
|
||
AgentId: _agentConfig.AgentId,
|
||
Content: $"[Fehler: {ex.Message}]",
|
||
Extra: new { role = "assistant", timestamp = DateTime.Now }));
|
||
}
|
||
});
|
||
}
|
||
|
||
private async Task LoadChatHistoryAsync()
|
||
{
|
||
if (_bridge is null) return;
|
||
|
||
var history = _engine.GetChatHistory(_agentConfig.AgentId);
|
||
await _bridge.SendAsync(new BridgeMessage(
|
||
Type: BridgeTypes.ChatHistory,
|
||
AgentId: _agentConfig.AgentId,
|
||
Extra: history.Select(e => new
|
||
{
|
||
role = e.Role,
|
||
content = e.Content,
|
||
timestamp = e.Timestamp
|
||
}).ToArray()));
|
||
}
|
||
|
||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||
{
|
||
_bridge?.Dispose();
|
||
base.OnFormClosed(e);
|
||
}
|
||
}
|