diff --git a/src/public/app/widgets/llm_chat/communication.ts b/src/public/app/widgets/llm_chat/communication.ts index 67d374af7..312fb9d5f 100644 --- a/src/public/app/widgets/llm_chat/communication.ts +++ b/src/public/app/widgets/llm_chat/communication.ts @@ -319,11 +319,34 @@ export async function setupStreamingResponse( // Handle completion if (message.done) { - console.log(`[${responseId}] Stream completed for session ${sessionId}, has content: ${!!message.content}, content length: ${message.content?.length || 0}, current response: ${assistantResponse.length} chars, post-tool response: ${postToolResponse.length} chars`); + console.log(`[${responseId}] Stream completed for session ${sessionId}, has content: ${!!message.content}, content length: ${message.content?.length || 0}, current response: ${assistantResponse.length} chars`); // Dump message content to console for debugging if (message.content) { console.log(`[${responseId}] CONTENT IN DONE MESSAGE (first 200 chars): "${message.content.substring(0, 200)}..."`); + + // Check if the done message contains the exact same content as our accumulated response + // We normalize by removing whitespace to avoid false negatives due to spacing differences + const normalizedMessage = message.content.trim(); + const normalizedResponse = assistantResponse.trim(); + + if (normalizedMessage === normalizedResponse) { + console.log(`[${responseId}] Final message is identical to accumulated response, no need to update`); + } + // If the done message is longer but contains our accumulated response, use the done message + else if (normalizedMessage.includes(normalizedResponse) && normalizedMessage.length > normalizedResponse.length) { + console.log(`[${responseId}] Final message is more complete than accumulated response, using it`); + assistantResponse = message.content; + } + // If the done message is different and not already included, append it to avoid duplication + else if (!normalizedResponse.includes(normalizedMessage) && normalizedMessage.length > 0) { + console.log(`[${responseId}] Final message has unique content, using it`); + assistantResponse = message.content; + } + // Otherwise, we already have the content accumulated, so no need to update + else { + console.log(`[${responseId}] Already have this content accumulated, not updating`); + } } // Clear timeout if set @@ -332,24 +355,6 @@ export async function setupStreamingResponse( timeoutId = null; } - // Make sure the final message is displayed - if (message.content) { - // If we've been collecting post-tool content, add this content to it - if (receivedPostToolContent) { - // Only add if it's not already included (avoid duplication) - if (!postToolResponse.includes(message.content)) { - postToolResponse += message.content; - console.log(`[${responseId}] Added final chunk to post-tool response`); - } - // Use the post-tool response as our final response - assistantResponse = postToolResponse; - } else if (!assistantResponse.includes(message.content)) { - // For standard responses, add any new content in the final message - console.log(`[${responseId}] Final message has unique content, using it`); - assistantResponse = message.content; - } - } - // Always mark as done when we receive the done flag onContentUpdate(assistantResponse, true); 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 e1033f451..721306269 100644 --- a/src/public/app/widgets/llm_chat/llm_chat_panel.ts +++ b/src/public/app/widgets/llm_chat/llm_chat_panel.ts @@ -996,18 +996,18 @@ export default class LlmChatPanel extends BasicWidget { */ private showToolExecutionInfo(toolExecutionData: any) { console.log(`Showing tool execution info: ${JSON.stringify(toolExecutionData)}`); - + // Enhanced debugging for tool execution if (!toolExecutionData) { console.error('Tool execution data is missing or undefined'); return; } - + // Check for required properties const actionType = toolExecutionData.action || ''; const toolName = toolExecutionData.tool || 'unknown'; console.log(`Tool execution details: action=${actionType}, tool=${toolName}, hasResult=${!!toolExecutionData.result}`); - + // Force action to 'result' if missing but result is present if (!actionType && toolExecutionData.result) { console.log('Setting missing action to "result" since result is present');