From 2486eee047782602d60cd669344e25b246a05682 Mon Sep 17 00:00:00 2001 From: Meleki Date: Wed, 11 Mar 2026 13:36:38 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20send=5Fto=5Fsession=20=E2=80=93=20fremde?= =?UTF-8?q?=20Sessions=20erlauben,=20Telegram-Notify,=20Fehler-Logging?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Program.cs | 1 + Services/AnthropicService.cs | 8 +++++- Services/DatabaseService.cs | 9 +++++++ Services/ToolService.cs | 50 ++++++++++++++++++++++++++---------- 4 files changed, 53 insertions(+), 15 deletions(-) diff --git a/Program.cs b/Program.cs index fe05f2b..ed2f39d 100644 --- a/Program.cs +++ b/Program.cs @@ -87,6 +87,7 @@ builder.Services.AddSingleton(); builder.Services.AddHostedService(sp => sp.GetRequiredService()); var app = builder.Build(); +app.Services.GetRequiredService().SetTelegramService(app.Services.GetRequiredService()); app.UseWebSockets(); app.UseDefaultFiles(); app.UseStaticFiles(); diff --git a/Services/AnthropicService.cs b/Services/AnthropicService.cs index 4fe7603..6a6a021 100644 --- a/Services/AnthropicService.cs +++ b/Services/AnthropicService.cs @@ -25,6 +25,7 @@ public class AnthropicService private readonly VectorSearchService _vectorSearch; private readonly EmbeddingBackgroundService _embeddingBg; private ChatService _chatService; + private TelegramService _telegramService; public AnthropicService(IHttpClientFactory httpFactory, string token, ToolService toolService, DatabaseService db, MemoryService memoryService = null, bool payloadLogging = false, bool payloadLoggingGzip = false, VectorSearchService vectorSearch = null, EmbeddingBackgroundService embeddingBg = null) { @@ -48,6 +49,11 @@ public class AnthropicService _chatService = chatService; } + public void SetTelegramService(TelegramService telegramService) + { + _telegramService = telegramService; + } + public async Task StreamChat( HttpResponse response, string modelId, @@ -1398,7 +1404,7 @@ public class AnthropicService string toolResult; bool isError = false; - try { toolResult = await _toolService.ExecuteTool(currentToolName, inputEl, workspace, _memoryService, agentId, workCt, remoteMgr: remoteMgr, sessionId: sessionId, vectorSearch: _vectorSearch, embeddingBg: _embeddingBg, db: _db, chatService: _chatService, anthropicService: this, userId: userId); } + try { toolResult = await _toolService.ExecuteTool(currentToolName, inputEl, workspace, _memoryService, agentId, workCt, remoteMgr: remoteMgr, sessionId: sessionId, vectorSearch: _vectorSearch, embeddingBg: _embeddingBg, db: _db, chatService: _chatService, anthropicService: this, userId: userId, telegramService: _telegramService); } catch (OperationCanceledException) { throw; } catch (Exception ex) { toolResult = $"Fehler: {ex.Message}"; isError = true; } diff --git a/Services/DatabaseService.cs b/Services/DatabaseService.cs index 4b794f7..fcef019 100644 --- a/Services/DatabaseService.cs +++ b/Services/DatabaseService.cs @@ -559,6 +559,15 @@ public class DatabaseService return session; } + public async Task GetSessionByName(string name) + { + using var conn = CreateConnection(); + var sessions = await conn.QueryAsync( + "SELECT * FROM sessions WHERE is_deleted = 0 AND LOWER(name) = LOWER(@name) ORDER BY updated_at DESC LIMIT 1", + new { name }); + return sessions.FirstOrDefault(); + } + public async Task> GetSessionsWithStats(string userId) { using var conn = CreateConnection(); diff --git a/Services/ToolService.cs b/Services/ToolService.cs index afd272d..079b52b 100644 --- a/Services/ToolService.cs +++ b/Services/ToolService.cs @@ -377,7 +377,7 @@ public class ToolService }; } - public async Task ExecuteTool(string name, JsonElement input, string workspace, MemoryService memoryService = null, string agentId = null, CancellationToken cancellationToken = default, RemoteConnectionManager remoteMgr = null, string sessionId = null, VectorSearchService vectorSearch = null, EmbeddingBackgroundService embeddingBg = null, DatabaseService db = null, ChatService chatService = null, AnthropicService anthropicService = null, string userId = null) + public async Task ExecuteTool(string name, JsonElement input, string workspace, MemoryService memoryService = null, string agentId = null, CancellationToken cancellationToken = default, RemoteConnectionManager remoteMgr = null, string sessionId = null, VectorSearchService vectorSearch = null, EmbeddingBackgroundService embeddingBg = null, DatabaseService db = null, ChatService chatService = null, AnthropicService anthropicService = null, string userId = null, TelegramService telegramService = null) { switch (name) { @@ -738,27 +738,19 @@ public class ToolService if (string.IsNullOrEmpty(message)) return "Fehler: message fehlt"; - // Ziel-Session per ID oder Name suchen + // Ziel-Session per ID oder Name suchen (instanzweit, kein User-Check) var targetSession = await db.GetSession(sessionIdOrName); - if (targetSession == null && !string.IsNullOrEmpty(userId)) - { - // Fallback: per Name suchen (case-insensitive) - var allSessions = await db.GetSessionsWithStats(userId); - targetSession = allSessions - .FirstOrDefault(s => string.Equals(s.Session.Name, sessionIdOrName, StringComparison.OrdinalIgnoreCase)) - ?.Session; - } + if (targetSession == null) + targetSession = await db.GetSessionByName(sessionIdOrName); if (targetSession == null) return $"Fehler: Session '{sessionIdOrName}' nicht gefunden"; - if (!string.IsNullOrEmpty(userId) && targetSession.UserId != userId) - return "Fehler: Zugriff auf diese Session nicht erlaubt"; var targetSessionId = targetSession.SessionId; if (targetSessionId == sessionId) return "Fehler: Kann keine Nachricht an die eigene Session senden"; // Context für Ziel-Session vorbereiten (analog zu CronjobService) - var ctx = await chatService.PrepareContext(targetSessionId, targetSession.UserId); + var ctx = await chatService.PrepareContext(targetSessionId, userId: null); if (ctx == null) return $"Fehler: Session '{targetSession.Name}' ist nicht konfiguriert (kein Agent zugewiesen?)"; @@ -771,9 +763,39 @@ public class ToolService var userContent = new List { new { type = "text", text = senderInfo } }; history.Add(new Dictionary { ["role"] = "user", ["content"] = userContent }); - await anthropicService.ChatNonStreaming(ctx, history); + try + { + await anthropicService.ChatNonStreaming(ctx, history); + } + catch (Exception ex) + { + Console.WriteLine($"[send_to_session] ChatNonStreaming Fehler: {ex}"); + return $"Fehler beim Senden an Session \"{targetSession.Name}\": {ex.Message}"; + } await db.UpdateSessionTimestamp(targetSessionId); + // Telegram-Benachrichtigung senden falls Session einen Bot hat + if (telegramService != null) + { + try + { + var updatedSession = await db.GetSession(targetSessionId); + if (updatedSession != null && !string.IsNullOrEmpty(updatedSession.TelegramChatId)) + { + var recentMsgs = await db.GetLatestActiveMessages(targetSessionId, 5); + var lastMsg = recentMsgs + .Where(m => m.Role == "assistant" && m.Type == "text") + .LastOrDefault(); + if (lastMsg != null) + await telegramService.SendNotification(targetSessionId, lastMsg.Content); + } + } + catch (Exception ex) + { + Console.WriteLine($"[send_to_session] Telegram-Benachrichtigung fehlgeschlagen: {ex.Message}"); + } + } + return $"Nachricht wurde erfolgreich an Session \"{targetSession.Name}\" gesendet. Der Agent dort hat geantwortet."; } default: