refactor: Chat-Payload vereinfacht + Inline-Bilder statt Platzhalter

Backend:
- ChatEndpoint empfängt nur noch content + sessionId (nicht mehr die gesamte History)
- History wird komplett aus DB aufgebaut via BuildHistoryFromDb
- Gelöschte Nachrichten (deleted_on) werden aus History gefiltert
- Leere Nachrichten werden übersprungen (kein API 400 mehr)
- BuildHistoryFromDb optimiert: nur Text für ältere Chains, Tool-Calls nur für aktuelle Chain
- GetChainMessages: includeDeleted-Parameter (Default: false)
- Archiv-Export nutzt includeDeleted: true

Frontend:
- messages[]-Array komplett entfernt (kein Client-seitiger History-State mehr)
- apiChat() sendet nur content + sessionId
- Inline-Bilder: [Bild: name] wird durch <img> ersetzt (live mit DataURL, History per API-Nachladen)
- _autoLoadImageAttachments() für History/Archiv/ältere Nachrichten
- Klick auf Inline-Bild öffnet Vollbild-Modal
This commit is contained in:
Meleki committed 2026-03-04 14:29:33 +01:00
1 parent 51db01752f
commit 8fc29c82d9
12 files changed
+222 -106

No files matched your search

+6 -10
View File
@@ -29,7 +29,6 @@ function addChainMetaBubble(d, streamed) {
// ── Chat State ──
const messages = [];
let isStreaming = false;
let pendingFiles = []; // [{ name, type, base64 }]
let pendingRefs = []; // [{ path, from, to }] - Workspace-Dateireferenzen
@@ -42,7 +41,6 @@ async function clearChat() {
const archive = await apiArchive(getCurrentSessionId());
if (!archive) return;
messages.length = 0;
chatEl().innerHTML = '';
lastKnownMessageId = 0;
loadedArchiveCount = 0;
@@ -100,6 +98,7 @@ async function sendMessage() {
clearPendingRefs();
}
let inlineImages = []; // Bilder für Inline-Anzeige
if (pendingFiles.length > 0) {
content = [];
const labels = [];
@@ -110,6 +109,9 @@ async function sendMessage() {
source: { type: 'base64', media_type: f.type, data: f.base64 },
_file_name: f.name
});
if (blockType === 'image') {
inlineImages.push({ name: f.name, dataUrl: 'data:' + f.type + ';base64,' + f.base64 });
}
labels.push('[' + (blockType === 'image' ? 'Bild' : 'Datei') + ': ' + f.name + ']');
}
if (msgText) content.push({ type: 'text', text: msgText });
@@ -120,8 +122,7 @@ async function sendMessage() {
bubbleText = msgText;
}
messages.push({ role: 'user', content });
addUserBubble(bubbleText, true);
addUserBubble(bubbleText, true, '', null, false, null, inlineImages);
input.value = '';
input.dispatchEvent(new Event('input'))
@@ -139,7 +140,7 @@ async function sendMessage() {
_chatAbandoned = false;
try {
const resp = await apiChat(messages, getCurrentSessionId(), _abortController.signal);
const resp = await apiChat(content, getCurrentSessionId(), _abortController.signal);
const reader = resp.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
@@ -206,11 +207,6 @@ async function sendMessage() {
case 'error':
endStreamBubble();
addErrorBubble(data.error, true);
// Fehlgeschlagene Message aus dem Array entfernen
// damit das kaputte Bild nicht endlos mitgeschickt wird
if (messages.length > 0 && messages[messages.length - 1].role === 'user') {
messages.pop();
}
break;
case 'done':