fix(llm): storing >1 message in a chat note works

fix(llm): storing >1 message in a chat note works
This commit is contained in:
perf3ct 2025-06-03 03:12:09 +00:00
parent d4d55b20a8
commit 336cd1fbda
No known key found for this signature in database
GPG Key ID: 569C4EEC436F5232
2 changed files with 27 additions and 37 deletions

View File

@ -1068,13 +1068,19 @@ export default class LlmChatPanel extends BasicWidget {
* Update the UI with streaming content * Update the UI with streaming content
*/ */
private updateStreamingUI(assistantResponse: string, isDone: boolean = false) { private updateStreamingUI(assistantResponse: string, isDone: boolean = false) {
// Get the existing assistant message or create a new one // Track if we have a streaming message in progress
let assistantMessageEl = this.noteContextChatMessages.querySelector('.assistant-message:last-child'); const hasStreamingMessage = !!this.noteContextChatMessages.querySelector('.assistant-message.streaming');
if (!assistantMessageEl) { // Create a new message element or use the existing streaming one
// If no assistant message yet, create one let assistantMessageEl: HTMLElement;
if (hasStreamingMessage) {
// Use the existing streaming message
assistantMessageEl = this.noteContextChatMessages.querySelector('.assistant-message.streaming')!;
} else {
// Create a new message element
assistantMessageEl = document.createElement('div'); assistantMessageEl = document.createElement('div');
assistantMessageEl.className = 'assistant-message message mb-3'; assistantMessageEl.className = 'assistant-message message mb-3 streaming';
this.noteContextChatMessages.appendChild(assistantMessageEl); this.noteContextChatMessages.appendChild(assistantMessageEl);
// Add assistant profile icon // Add assistant profile icon
@ -1089,35 +1095,30 @@ export default class LlmChatPanel extends BasicWidget {
assistantMessageEl.appendChild(messageContent); assistantMessageEl.appendChild(messageContent);
} }
// Update the content with the current response (no thinking content removal) // Update the content with the current response
const messageContent = assistantMessageEl.querySelector('.message-content') as HTMLElement; const messageContent = assistantMessageEl.querySelector('.message-content') as HTMLElement;
messageContent.innerHTML = formatMarkdown(assistantResponse); messageContent.innerHTML = formatMarkdown(assistantResponse);
// Apply syntax highlighting if this is the final update // When the response is complete
if (isDone) { if (isDone) {
// Remove the streaming class to mark this message as complete
assistantMessageEl.classList.remove('streaming');
// Apply syntax highlighting
formatCodeBlocks($(assistantMessageEl as HTMLElement)); formatCodeBlocks($(assistantMessageEl as HTMLElement));
// Hide the thinking display when response is complete // Hide the thinking display when response is complete
this.hideThinkingDisplay(); this.hideThinkingDisplay();
// Update message in the data model for storage // Always add a new message to the data model
// Find the last assistant message to update, or add a new one if none exists // This ensures we preserve all distinct assistant messages
const assistantMessages = this.messages.filter(msg => msg.role === 'assistant');
const lastAssistantMsgIndex = assistantMessages.length > 0 ?
this.messages.lastIndexOf(assistantMessages[assistantMessages.length - 1]) : -1;
if (lastAssistantMsgIndex >= 0) {
// Update existing message
this.messages[lastAssistantMsgIndex].content = assistantResponse;
} else {
// Add new message
this.messages.push({ this.messages.push({
role: 'assistant', role: 'assistant',
content: assistantResponse content: assistantResponse,
timestamp: new Date()
}); });
}
// Save the data // Save the updated message list
this.saveCurrentData(); this.saveCurrentData();
} }

View File

@ -963,21 +963,10 @@ async function streamMessage(req: Request, res: Response) {
error: `Error processing message: ${error}`, error: `Error processing message: ${error}`,
done: true done: true
}); });
// Only write to the response if it hasn't been ended yet
if (!res.writableEnded) {
res.write(`data: ${JSON.stringify({ error: `Error processing message: ${error}`, done: true })}\n\n`);
res.end();
}
} }
} catch (error: any) { } catch (error: any) {
log.error(`Error starting message stream: ${error.message}`); log.error(`Error starting message stream: ${error.message}`);
log.error(`Error starting message stream, can't communicate via WebSocket: ${error.message}`);
// Only write to the response if it hasn't been ended yet
if (!res.writableEnded) {
res.write(`data: ${JSON.stringify({ error: `Error starting message stream: ${error.message}`, done: true })}\n\n`);
res.end();
}
} }
} }