Files
ClawdDotNet/frm_chat.cs
T
RichardandClaude Opus 4.8 2fed388c99 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>
2026-07-26 18:21:46 +02:00

166 lines
5.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}