diff --git a/src/public/app/widgets/llm_chat_panel.ts b/src/public/app/widgets/llm_chat_panel.ts index 6f7ebbbc8..3c434893c 100644 --- a/src/public/app/widgets/llm_chat_panel.ts +++ b/src/public/app/widgets/llm_chat_panel.ts @@ -125,9 +125,9 @@ export default class LlmChatPanel extends BasicWidget { this.initializeEventListeners(); - // Create a session when first loaded - this.createChatSession(); - + // Don't create a session here - wait for refresh + // This prevents the wrong session from being created for the wrong note + return this.$widget; } @@ -153,7 +153,12 @@ export default class LlmChatPanel extends BasicWidget { try { const data = await this.onGetData(); - console.log("Loaded chat data:", data); + console.log(`Loading chat data for noteId: ${this.currentNoteId}`, data); + + // Make sure we're loading data for the correct note + if (data && data.noteId && data.noteId !== this.currentNoteId) { + console.warn(`Data noteId ${data.noteId} doesn't match current noteId ${this.currentNoteId}`); + } if (data && data.messages && Array.isArray(data.messages)) { // Clear existing messages in the UI @@ -171,11 +176,12 @@ export default class LlmChatPanel extends BasicWidget { // Scroll to bottom this.chatContainer.scrollTop = this.chatContainer.scrollHeight; + console.log(`Successfully loaded ${data.messages.length} messages for noteId: ${this.currentNoteId}`); return true; } } catch (e) { - console.error("Error loading saved chat data:", e); + console.error(`Error loading saved chat data for noteId: ${this.currentNoteId}:`, e); } return false; @@ -191,13 +197,16 @@ export default class LlmChatPanel extends BasicWidget { } try { + // Include the current note ID for tracking purposes await this.onSaveData({ messages: this.messages, - lastUpdated: new Date() + lastUpdated: new Date(), + noteId: this.currentNoteId // Include the note ID to help with debugging }); + console.log(`Saved chat data for noteId: ${this.currentNoteId} with ${this.messages.length} messages`); return true; } catch (e) { - console.error("Error saving chat data:", e); + console.error(`Error saving chat data for noteId: ${this.currentNoteId}:`, e); return false; } } @@ -211,12 +220,26 @@ export default class LlmChatPanel extends BasicWidget { await this.validateEmbeddingProviders(); // Get current note context if needed - this.currentNoteId = appContext.tabManager.getActiveContext()?.note?.noteId || null; + const currentActiveNoteId = appContext.tabManager.getActiveContext()?.note?.noteId || null; - // Try to load saved data + // If we're switching to a different note, we need to reset + if (this.currentNoteId !== currentActiveNoteId) { + console.log(`Note ID changed from ${this.currentNoteId} to ${currentActiveNoteId}, resetting chat panel`); + + // Reset the UI and data + this.noteContextChatMessages.innerHTML = ''; + this.messages = []; + this.sessionId = null; + this.hideSources(); // Hide any sources from previous note + + // Update our current noteId + this.currentNoteId = currentActiveNoteId; + } + + // Always try to load saved data for the current note const hasSavedData = await this.loadSavedData(); - // Only create a new session if we don't have saved data + // Only create a new session if we don't have a session or saved data if (!this.sessionId || !hasSavedData) { // Create a new chat session await this.createChatSession(); diff --git a/src/public/app/widgets/type_widgets/ai_chat.ts b/src/public/app/widgets/type_widgets/ai_chat.ts index 846540068..113ab4377 100644 --- a/src/public/app/widgets/type_widgets/ai_chat.ts +++ b/src/public/app/widgets/type_widgets/ai_chat.ts @@ -32,15 +32,37 @@ export default class AiChatTypeWidget extends TypeWidget { return this.$widget; } + // Override the refreshWithNote method to ensure we get note changes + async refreshWithNote(note: FNote | null | undefined) { + console.log("refreshWithNote called for note:", note?.noteId); + + // Always force a refresh when the note changes + if (this.note?.noteId !== note?.noteId) { + console.log(`Note ID changed from ${this.note?.noteId} to ${note?.noteId}, forcing reset`); + this.isInitialized = false; + this.initPromise = null; + + // Force refresh the chat panel with the new note + if (note) { + this.llmChatPanel.currentNoteId = note.noteId; + } + } + + // Continue with regular doRefresh + await this.doRefresh(note); + } + async doRefresh(note: FNote | null | undefined) { try { + console.log("doRefresh called for note:", note?.noteId); + // If we're already initializing, wait for that to complete if (this.initPromise) { await this.initPromise; return; } - // Only initialize once + // Initialize once or when note changes if (!this.isInitialized) { console.log("Initializing AI Chat Panel for note:", note?.noteId); @@ -53,7 +75,8 @@ export default class AiChatTypeWidget extends TypeWidget { // Initialize with empty chat history await this.saveData({ messages: [], - title: note.title + title: note.title, + noteId: note.noteId // Store the note ID in the data }); console.log("Initialized empty chat history for new note"); } else { @@ -67,6 +90,10 @@ export default class AiChatTypeWidget extends TypeWidget { // Create a promise to track initialization this.initPromise = (async () => { try { + // Reset the UI before refreshing + this.llmChatPanel.noteContextChatMessages.innerHTML = ''; + this.llmChatPanel.messages = []; + // This will load saved data via the getData callback await this.llmChatPanel.refresh(); this.isInitialized = true; @@ -89,24 +116,61 @@ export default class AiChatTypeWidget extends TypeWidget { // We don't need to refresh on entities reloaded for the chat } - async activeContextChangedEvent(data: EventData<"activeContextChanged">) { - // Only initialize if this becomes active and we're not initialized yet - if (this.isActive() && !this.isInitialized && !this.initPromise) { - try { - this.initPromise = (async () => { - try { - await this.llmChatPanel.refresh(); - this.isInitialized = true; - } catch (e) { - console.error("Error initializing LlmChatPanel:", e); - } - })(); + async noteSwitched() { + console.log("Note switched to:", this.noteId); + + // Force a full reset when switching notes + this.isInitialized = false; + this.initPromise = null; + + if (this.note) { + // Update the chat panel with the new note ID before refreshing + this.llmChatPanel.currentNoteId = this.note.noteId; + + // Reset the chat panel UI + this.llmChatPanel.noteContextChatMessages.innerHTML = ''; + this.llmChatPanel.messages = []; + this.llmChatPanel.sessionId = null; + } + + // Call the parent method to refresh + await super.noteSwitched(); + } - await this.initPromise; - this.initPromise = null; - } catch (e) { - console.error("Error in activeContextChangedEvent:", e); + async activeContextChangedEvent(data: EventData<"activeContextChanged">) { + if (!this.isActive()) { + return; + } + + console.log("Active context changed, refreshing AI Chat Panel"); + + // Always refresh when we become active - this ensures we load the correct note data + try { + // Reset initialization flag to force a refresh + this.isInitialized = false; + + // Make sure the chat panel has the current note ID + if (this.note) { + this.llmChatPanel.currentNoteId = this.note.noteId; } + + this.initPromise = (async () => { + try { + // Reset the UI before refreshing + this.llmChatPanel.noteContextChatMessages.innerHTML = ''; + this.llmChatPanel.messages = []; + + await this.llmChatPanel.refresh(); + this.isInitialized = true; + } catch (e) { + console.error("Error refreshing LlmChatPanel:", e); + } + })(); + + await this.initPromise; + this.initPromise = null; + } catch (e) { + console.error("Error in activeContextChangedEvent:", e); } }