From 92e252aa38b577781a582f33fdb1341975c8d160 Mon Sep 17 00:00:00 2001 From: Ayush Pal <144852243+Ayushpal2006@users.noreply.github.com> Date: Mon, 3 Aug 2026 03:50:19 +0530 Subject: [PATCH] Route streamed LLM events to target windows instead of broadcasting --- main.js | 40 +++++++++------------------------- src/managers/window.manager.js | 32 +++++++++++++++++++-------- 2 files changed, 33 insertions(+), 39 deletions(-) diff --git a/main.js b/main.js index 36ccf4b..35c07a3 100644 --- a/main.js +++ b/main.js @@ -1092,7 +1092,7 @@ class ApplicationController { this._responseSeq = (this._responseSeq || 0) + 1; const messageId = `img-${Date.now()}-${this._responseSeq}`; - windowManager.broadcastToAllWindows("transcription-llm-response-start", { + this.sendToVoiceResponseWindows("transcription-llm-response-start", { messageId, skill: this.activeSkill }); @@ -1104,7 +1104,7 @@ class ApplicationController { sessionHistory.recent, needsProgrammingLanguage ? this.codingLanguage : null, (delta) => { - windowManager.broadcastToAllWindows("transcription-llm-response-chunk", { + this.sendToVoiceResponseWindows("transcription-llm-response-chunk", { messageId, delta }); @@ -1119,7 +1119,7 @@ class ApplicationController { isImageAnalysis: true }); - this.broadcastTranscriptionLLMResponse(llmResult); + this.sendTranscriptionLLMResponseToVoiceTargets(llmResult); windowManager.showLLMResponse(llmResult.response, { skill: this.activeSkill, @@ -1158,7 +1158,7 @@ class ApplicationController { this._responseSeq = (this._responseSeq || 0) + 1; const messageId = `chat-${Date.now()}-${this._responseSeq}`; - windowManager.broadcastToAllWindows("transcription-llm-response-start", { + this.sendToVoiceResponseWindows("transcription-llm-response-start", { messageId, skill: this.activeSkill }); @@ -1170,7 +1170,7 @@ class ApplicationController { sessionHistory.recent, needsProgrammingLanguage ? this.codingLanguage : null, (delta) => { - windowManager.broadcastToAllWindows("transcription-llm-response-chunk", { + this.sendToVoiceResponseWindows("transcription-llm-response-chunk", { messageId, delta }); @@ -1193,7 +1193,7 @@ class ApplicationController { usedFallback: llmResult.metadata.usedFallback, }); - this.broadcastTranscriptionLLMResponse(llmResult); + this.sendTranscriptionLLMResponseToVoiceTargets(llmResult); windowManager.showLLMResponse(llmResult.response, { skill: this.activeSkill, @@ -1472,30 +1472,13 @@ class ApplicationController { } broadcastTranscriptionLLMResponse(llmResult) { - const broadcastData = { - response: llmResult.response, - metadata: llmResult.metadata, - messageId: llmResult.metadata && llmResult.metadata.messageId, - skill: this.activeSkill, - isTranscriptionResponse: true - }; - - logger.info("Broadcasting transcription LLM response to all windows", { - responseLength: llmResult.response.length, - skill: this.activeSkill, - responsePreview: llmResult.response.substring(0, 100) + "..." - }); - - windowManager.broadcastToAllWindows("transcription-llm-response", broadcastData); + this.sendTranscriptionLLMResponseToVoiceTargets(llmResult); } sendToChatWindow(channel, data) { - const chatWindow = windowManager.getWindow("chat"); - if (!chatWindow || chatWindow.isDestroyed()) { - logger.warn("Chat window unavailable for speech event", { channel }); - return; + if (!windowManager.sendToWindow("chat", channel, data)) { + logger.warn("Chat window unavailable for event", { channel }); } - chatWindow.webContents.send(channel, data); } getVoiceResponseTarget() { @@ -1513,10 +1496,7 @@ class ApplicationController { this.sendToChatWindow(channel, data); } if (target === 'overlay' || target === 'both') { - const responseWindow = windowManager.getWindow("llmResponse"); - if (responseWindow && !responseWindow.isDestroyed()) { - responseWindow.webContents.send(channel, data); - } + windowManager.sendToWindow("llmResponse", channel, data); } } diff --git a/src/managers/window.manager.js b/src/managers/window.manager.js index 52fa81b..a8c1407 100644 --- a/src/managers/window.manager.js +++ b/src/managers/window.manager.js @@ -1460,6 +1460,15 @@ class WindowManager { }); } + sendToWindow(type, channel, data) { + const window = this.windows.get(type); + if (window && !window.isDestroyed()) { + window.webContents.send(channel, data); + return true; + } + return false; + } + broadcastToAllWindows(channel, data) { const windowStates = {}; @@ -1476,15 +1485,20 @@ class WindowManager { } }); - logger.info('Broadcast sent to all windows', { - channel, - windowCount: this.windows.size, - windowStates, - dataKeys: data ? Object.keys(data) : [], - // Fixed: Check for 'content' instead of 'response' to match actual data structure - dataPreview: data && data.content ? data.content.substring(0, 50) + '...' : - data && data.response ? data.response.substring(0, 50) + '...' : 'No response' - }); + // Log at debug level for high-frequency streaming chunk events to reduce per-chunk log overhead + if (channel.endsWith('-chunk') || channel.includes('chunk')) { + logger.debug('Broadcast sent to all windows', { channel, windowCount: this.windows.size }); + } else { + logger.info('Broadcast sent to all windows', { + channel, + windowCount: this.windows.size, + windowStates, + dataKeys: data ? Object.keys(data) : [], + // Fixed: Check for 'content' instead of 'response' to match actual data structure + dataPreview: data && data.content ? data.content.substring(0, 50) + '...' : + data && data.response ? data.response.substring(0, 50) + '...' : 'No response' + }); + } } getWindow(type) {