From e31daa23857120e842aa1c731ef82a7a1f3dde3e Mon Sep 17 00:00:00 2001 From: Meleki Date: Sun, 1 Mar 2026 15:48:19 +0100 Subject: [PATCH] feat: Chat-History auf max. 500 Nachrichten limitieren --- Endpoints/HistoryEndpoint.cs | 23 +++++++++++++++++++---- Services/DatabaseService.cs | 22 ++++++++++++++++++++++ TODO.md | 2 +- wwwroot/js/history.js | 13 +++++++++++-- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/Endpoints/HistoryEndpoint.cs b/Endpoints/HistoryEndpoint.cs index 4667c88..99ab069 100644 --- a/Endpoints/HistoryEndpoint.cs +++ b/Endpoints/HistoryEndpoint.cs @@ -33,16 +33,31 @@ public static class HistoryEndpoint return; } + const int messageLimit = 500; + + var totalCount = await db.GetActiveMessageCount(sessionId); + var messages = await db.GetLatestActiveMessages(sessionId, messageLimit); + + // Nach Chain gruppieren (Reihenfolge beibehalten) + var chainIds = messages.Select(m => m.ChainId).Distinct().ToList(); var chains = await db.GetActiveChains(sessionId); + var chainMap = chains.ToDictionary(c => c.ChainId); var result = new List(); - foreach (var chain in chains) + foreach (var chainId in chainIds) { - var messages = await db.GetChainMessages(chain.ChainId); - result.Add(new { chain, messages }); + chainMap.TryGetValue(chainId, out var chain); + var chainMessages = messages.Where(m => m.ChainId == chainId).ToList(); + result.Add(new { chain, messages = chainMessages }); } - await ctx.Response.WriteAsJsonAsync(result); + await ctx.Response.WriteAsJsonAsync(new + { + entries = result, + hasMore = totalCount > messageLimit, + totalCount, + loadedCount = messages.Count + }); } private static async Task HandlePoll(HttpContext ctx, DatabaseService db) diff --git a/Services/DatabaseService.cs b/Services/DatabaseService.cs index 0b96b85..9e988ea 100644 --- a/Services/DatabaseService.cs +++ b/Services/DatabaseService.cs @@ -492,6 +492,28 @@ public class DatabaseService ); } + public async Task GetActiveMessageCount(string sessionId) + { + using var conn = CreateConnection(); + return await conn.ExecuteScalarAsync(@" + SELECT COUNT(*) FROM messages m + JOIN chains c ON m.chain_id = c.chain_id + WHERE c.archive_id IS NULL AND c.session_id = @sessionId", + new { sessionId }); + } + + public async Task> GetLatestActiveMessages(string sessionId, int limit) + { + using var conn = CreateConnection(); + var messages = await conn.QueryAsync(@" + SELECT m.* FROM messages m + JOIN chains c ON m.chain_id = c.chain_id + WHERE c.archive_id IS NULL AND c.session_id = @sessionId + ORDER BY m.id DESC LIMIT @limit", + new { sessionId, limit }); + return messages.Reverse().ToList(); + } + public async Task> GetActiveMessagesAfterId(string sessionId, long afterId, int limit = 200) { using var conn = CreateConnection(); diff --git a/TODO.md b/TODO.md index 24f3bfa..849744e 100644 --- a/TODO.md +++ b/TODO.md @@ -7,7 +7,7 @@ - [ ] Subagents: Möglichkeit Subagents zu starten und zu orchestrieren - [x] Im Chat: Menüpunkt "Datenbank sichern" entfernen und stattdessen in den Einstellungen platzieren. Außerdem soll nun nicht mehr nur die Datenbank gesichert werden, sondern der gesamte data-Ordner (der Unterordner backup muss natürlich exkludiert werden) - [ ] Agents-Formular (nur beim Bearbeiten von vorhandenen Agent): Button der das File-Explorer Modal öffnet bei dem ich den Agent-Ordner sehe. -- [ ] Chat: Maximal 500 Nachrichten laden. Dauert sonst zu lange und der Browser wird langsam +- [x] Chat: Maximal 500 Nachrichten laden. Dauert sonst zu lange und der Browser wird langsam ## Bugs - [x] Wenn gerade gestreamt wird und man refreshed die Seite, dann verliert das Frontend den Status "Streaming..." und ich kann eine Nachricht schreiben, obwohl das nicht möglich sein sollte diff --git a/wwwroot/js/history.js b/wwwroot/js/history.js index 5bc1258..98009b0 100644 --- a/wwwroot/js/history.js +++ b/wwwroot/js/history.js @@ -13,9 +13,18 @@ async function loadHistory() { } const data = await apiHistory(sid); - data.reverse(); + const entries = data.entries || []; + entries.reverse(); - for (const entry of data) { + if (data.hasMore) { + const skipped = data.totalCount - data.loadedCount; + const info = document.createElement('div'); + info.className = 'msg system-info'; + info.innerHTML = ` ${skipped} ältere Nachrichten nicht geladen`; + chatEl().appendChild(info); + } + + for (const entry of entries) { renderMessages(entry.messages, true); if (entry.chain) addChainMetaBubble(entry.chain, false); }