diff --git a/src/public/app/widgets/llm_chat/llm_chat_panel.ts b/src/public/app/widgets/llm_chat/llm_chat_panel.ts index 0e79e1497..ed4415df6 100644 --- a/src/public/app/widgets/llm_chat/llm_chat_panel.ts +++ b/src/public/app/widgets/llm_chat/llm_chat_panel.ts @@ -251,42 +251,8 @@ export default class LlmChatPanel extends BasicWidget { console.log(`Saving chat data with sessionId: ${this.sessionId}, noteId: ${this.noteId}, ${toolSteps.length} tool steps, ${this.sources?.length || 0} sources, ${toolExecutions.length} tool executions`); // Save the data to the note attribute via the callback + // This is the ONLY place we should save data, letting the container widget handle persistence await this.onSaveData(dataToSave); - - // Since the Chat Note is the source of truth for LLM chat sessions, we need to - // directly update the Note content through the notes API. - // The noteId is the actual noteId for the Chat Note - if (this.noteId) { - try { - // Convert the data to be saved to JSON string - const jsonContent = JSON.stringify({ - messages: this.messages, - metadata: { - model: this.metadata?.model || 'default', - provider: this.metadata?.provider || undefined, - temperature: this.metadata?.temperature || 0.7, - lastUpdated: new Date().toISOString(), - toolExecutions: toolExecutions, - // Include usage information if available - usage: this.metadata?.usage, - sources: this.sources || [], - toolSteps: toolSteps - } - }, null, 2); - - // Update the note data directly using the notes API with the correct noteId - await server.put(`notes/${this.noteId}/data`, { - content: jsonContent - }); - - console.log(`Updated Chat Note (${this.noteId}) content directly`); - } catch (apiError) { - console.error('Error updating Chat Note content:', apiError); - console.error('Check if the noteId is correct:', this.noteId); - } - } else { - console.error('Cannot update Chat Note - noteId is not set'); - } } catch (error) { console.error('Error saving chat data:', error); } diff --git a/src/public/app/widgets/type_widgets/ai_chat.ts b/src/public/app/widgets/type_widgets/ai_chat.ts index 96927f13b..c4d758a7d 100644 --- a/src/public/app/widgets/type_widgets/ai_chat.ts +++ b/src/public/app/widgets/type_widgets/ai_chat.ts @@ -181,8 +181,24 @@ export default class AiChatTypeWidget extends TypeWidget { } try { + console.log(`AiChatTypeWidget: Saving data for note ${this.note.noteId}`); + + // Format the data properly - this is the canonical format of the data + const formattedData = { + messages: data.messages || [], + sessionId: data.sessionId, + noteId: data.noteId || this.note.noteId, + toolSteps: data.toolSteps || [], + sources: data.sources || [], + metadata: { + ...(data.metadata || {}), + lastUpdated: new Date().toISOString() + } + }; + + // Save the data to the note await server.put(`notes/${this.note.noteId}/data`, { - content: JSON.stringify(data, null, 2) + content: JSON.stringify(formattedData, null, 2) }); } catch (e) { console.error("Error saving AI Chat data:", e); @@ -197,13 +213,41 @@ export default class AiChatTypeWidget extends TypeWidget { } try { + console.log(`AiChatTypeWidget: Getting data for note ${this.note.noteId}`); const content = await this.note.getContent(); if (!content) { + console.log("Note content is empty"); return null; } - return JSON.parse(content as string); + // Parse the content as JSON + let parsedContent; + try { + parsedContent = JSON.parse(content as string); + console.log("Successfully parsed note content as JSON"); + } catch (e) { + console.error("Error parsing chat content as JSON:", e); + return null; + } + + // Check if this is a blob response with 'content' property that needs to be parsed again + // This happens when the content is returned from the /blob endpoint + if (parsedContent.content && typeof parsedContent.content === 'string' && + parsedContent.blobId && parsedContent.contentLength) { + try { + // The actual chat data is inside the 'content' property as a string + console.log("Detected blob response structure, parsing inner content"); + const innerContent = JSON.parse(parsedContent.content); + console.log("Successfully parsed blob inner content"); + return innerContent; + } catch (innerError) { + console.error("Error parsing inner blob content:", innerError); + return null; + } + } + + return parsedContent; } catch (e) { console.error("Error loading AI Chat data:", e); return null;