diff --git a/Directory.Build.props b/Directory.Build.props
index 2a69c8f6..83587a34 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -59,6 +59,7 @@
${highlighted}${highlighted}
' + escaped + '
';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '' + escaped + '
';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n // Update the existing message\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? ''\n : '';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement\n ? this.inputElement.getAttribute('data-profile-id')\n : null;\n },\n setSessionId(sessionId) {\n if (!this.inputElement) {\n return;\n }\n\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.rejectPendingSessionRequest('Session was reset.');\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onSessionReset === 'function') {\n widgetBehavior.onSessionReset(this, config);\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.requestNewSession(profileId).catch(err => console.error(err));\n },\n async ensureSessionForDocuments(profileId) {\n var sessionId = this.getSessionId();\n if (sessionId) {\n return sessionId;\n }\n\n if (!profileId || !this.connection) {\n return null;\n }\n\n return await this.requestNewSession(profileId);\n },\n requestNewSession(profileId) {\n if (this.pendingSessionPromise) {\n return this.pendingSessionPromise;\n }\n\n if (!profileId || !this.connection) {\n return Promise.resolve(null);\n }\n\n this.pendingSessionPromise = new Promise((resolve, reject) => {\n this.pendingSessionResolver = resolve;\n this.pendingSessionRejector = reject;\n this.pendingSessionTimeoutId = window.setTimeout(() => {\n this.rejectPendingSessionRequest('Timed out while creating a chat session.');\n }, 15000);\n });\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => {\n this.rejectPendingSessionRequest(err);\n });\n\n return this.pendingSessionPromise;\n },\n resolvePendingSessionRequest(sessionId) {\n if (this.pendingSessionResolver) {\n this.pendingSessionResolver(sessionId);\n }\n\n this.clearPendingSessionRequest();\n },\n rejectPendingSessionRequest(error) {\n if (this.pendingSessionRejector) {\n this.pendingSessionRejector(error);\n }\n\n this.clearPendingSessionRequest();\n },\n clearPendingSessionRequest() {\n if (this.pendingSessionTimeoutId) {\n window.clearTimeout(this.pendingSessionTimeoutId);\n }\n\n this.pendingSessionPromise = null;\n this.pendingSessionResolver = null;\n this.pendingSessionRejector = null;\n this.pendingSessionTimeoutId = null;\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n\n if (!this.inputElement || !this.buttonElement || !this.chatContainer || !this.placeholder) {\n console.error('AI chat app could not initialize because one or more required elements were not found.', {\n inputElementSelector: config.inputElementSelector,\n sendButtonElementSelector: config.sendButtonElementSelector,\n chatContainerElementSelector: config.chatContainerElementSelector,\n placeholderElementSelector: config.placeholderElementSelector\n });\n\n return false;\n }\n\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n\n return true;\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n if (sessionId && this.getSessionId() === sessionId) {\n this.resolvePendingSessionRequest(sessionId);\n }\n\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n this.resolvePendingSessionRequest(sessionId);\n\n if (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {\n widgetBehavior.onSessionInitialized(this, sessionId, config);\n }\n },\n getSessionId() {\n let sessionId = this.inputElement\n ? this.inputElement.getAttribute('data-session-id')\n : null;\n\n if (!sessionId && widgetBehavior && typeof widgetBehavior.resolveSessionId === 'function') {\n sessionId = widgetBehavior.resolveSessionId(this, config);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Keep feedback icons as simple span-based Font Awesome markup so\n // later state updates do not depend on i2svg replacement.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('span');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('span');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() {\n this.renderDocumentBar();\n if (widgetBehavior && typeof widgetBehavior.onDocumentsChanged === 'function') {\n widgetBehavior.onDocumentsChanged(this, this.documents, config);\n }\n },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isDocumentOperationPending() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n const isInitialized = this.initializeApp();\n if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {\n widgetBehavior.onMounted(this, config);\n }\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onBeforeUnmount === 'function') {\n widgetBehavior.onBeforeUnmount(this, config);\n }\n },\n template: config.messageTemplate\n };\n\n const app = Vue.createApp(appDefinition).mount(config.appElementSelector);\n\n if (widgetBehavior && typeof widgetBehavior.attach === 'function') {\n widgetBehavior.attach(app, config);\n }\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]} +{"version":3,"sources":["ai-chat.js"],"names":["e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","setPrototypeOf","__proto__","displayName","_regenerator","w","m","defineProperty","_regeneratorDefine","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","openAIChatManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","codeCopiedText","widget","chatWidgetContainer","chatWidgetStateName","chatHistorySection","showHistoryButton","closeHistoryButton","newChatButton","toggleButtonSelector","resetSizeButtonSelector","dragHandleSelector","enableDragging","enableResizing","persistLayout","defaultWidth","defaultHeight","minWidth","minHeight","messageTemplate","indicatorTemplate","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","containsFontAwesomePlaceholders","root","nodeType","selector","matches","querySelector","refreshFontAwesomeIcons","fontAwesome","FontAwesome","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","parsePixelValue","Number","isFinite","parsed","parseFloat","clamp","min","max","Math","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","getCitationLabel","buildCitationDisplay","content","processedContent","messageReferences","keys","citations","citedRefs","filter","_ref6","_ref7","includes","sort","_ref8","_ref9","_ref0","_ref1","b","displayIndex","_iterator","_step","_step$value","placeholder","concat","replaceAll","referenceKey","label","isDownload","err","_i2","_citations","citation","map","_ref10","_excluded","buildCopyContent","copyContent","_iterator2","_step2","_iterator3","_step3","trimEnd","updateMessagePresentation","message","rawContent","citationDisplay","displayContent","citationReferences","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","__chartConfigs","createChartHtml","chartId","use","extensions","level","start","idx","undefined","tokenizer","extracted","tryExtractChartMarker","startIndex","type","raw","substring","endIndex","json","token","config","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","renderChartsInMessage","charts","requestAnimationFrame","_iterator4","_step4","renderChartOnCanvas","canvas","getElementById","Chart","console","warn","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","renderPendingCharts","configs","_i3","_Object$keys","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","initialize","instanceConfig","hasWidgetConfig","widgetBehavior","openAIChatWidgetBehavior","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","appDefinition","inputElement","buttonElement","chatContainer","isSessionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","notifications","prompt","documents","existingDocuments","isUploading","isDocumentOperationPending","documentOperationQueue","uploadErrors","isDragOver","documentBar","metricsEnabled","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","pendingSessionPromise","pendingSessionResolver","pendingSessionRejector","pendingSessionTimeoutId","computed","lastAssistantIndex","role","methods","handleBeforeUnload","handleDragOver","sessionDocumentsEnabled","preventDefault","stopPropagation","inputArea","closest","classList","add","handleDragLeave","remove","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","target","queueDocumentOperation","operation","self","previousOperation","nextOperation","_callee","_context","_this","_callee3","filesToUpload","_context3","uploadDocumentUrl","_callee2","sessionId","profileId","formData","response","errorText","uploadError","result","_t","_t2","_context2","getSessionId","getProfileId","ensureSessionForDocuments","fileName","renderDocumentBar","FormData","append","fetch","method","body","ok","extractReadableErrorMessage","initializeSession","uploaded","failed","reloadCurrentSession","removeDocument","doc","_this2","_callee5","_context5","removeDocumentUrl","_callee4","removeError","_t3","_context4","headers","stringify","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","closeButtons","querySelectorAll","j","addEventListener","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","div","fallbackMessage","startsWith","detail","normalizeAssistantAppearance","appearance","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this3","_callee6","_t4","_context6","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","handleReceiveError","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","escaped","replace","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","responseId","hideTypingIndicator","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","autoCreateSession","startNewSession","onclose","addMessageInternal","_this4","fireEvent","CustomEvent","_this5","_message$rawContent","addMessages","_this6","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","style","display","conversationButtonElement","event","isIndicator","trimmedPrompt","streamMessage","startRecording","_this7","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","subject","Subject","pendingChunk","size","_callee7","uint8Array","base64","_context7","arrayBuffer","reduce","str","byte","String","fromCharCode","btoa","getTracks","track","stop","complete","documentElement","send","updateMicButton","toggleRecording","sessionProfileId","_this8","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i4","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_this8$stream","processReferences","streamingFinished","synthesizeSpeech","_this8$stream2","getServiceDownMessage","_this9","_ref15","_message$rawContent2","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this0","buttons","button","buttonIndex","isPlaying","iconHtml","toggle","cacheIndex","_this1","_ttsCacheIndex","invoke","toggleMessageTts","_this10","playAudioBlob","_this11","totalLength","sum","combined","offset","_iterator5","_step5","set","blob","Blob","_this12","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","_this13","nextBlob","shift","conversationModeOnAudioEnded","_this14","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this15","updateConversationButton","_conversationSubject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","micSource","createMediaStreamSource","connect","analyser","interruptVolumeThreshold","freqData","frequencyBinCount","getByteFrequencyData","k","avg","_callee8","_context8","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","element","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","location","origin","searchParams","originalLength","removedCount","_this16","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this17","setTimeout","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this18","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","rejectPendingSessionRequest","sessionRating","onSessionReset","requestNewSession","_this19","_callee9","_context9","_this20","reject","resolvePendingSessionRequest","clearPendingSessionRequest","initializeApp","_this21","placeholderElementSelector","loadSession","documentBarSelector","className","multiple","allowedExtensions","accept","parentElement","appendChild","threshold","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","btn","block","codeEl","clipboard","writeText","copiedText","micButtonElementSelector","conversationButtonElementSelector","force","onSessionInitialized","resolveSessionId","copyResponse","_ref17","_message$copyContent","updateFeedbackIcons","container","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","removeEventListener","watch","handler","onDocumentsChanged","deep","active","mounted","_this22","_callee0","isInitialized","_context0","onMounted","fontAwesomeObserver","beforeUnmount","disconnect","onBeforeUnmount","template","app","Vue","createApp","mount","attach","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.js","sourcesContent":["window.openAIChatManager = function () {\n\n // Defaults (can be overridden by instanceConfig)\n var defaultConfig = {\n // UI defaults for generated media\n generatedImageAltText: 'Generated Image',\n generatedImageMaxWidth: 400,\n downloadImageTitle: 'Download image',\n downloadChartTitle: 'Download chart as image',\n downloadChartButtonText: 'Download',\n userLabel: 'You',\n assistantLabel: 'Assistant',\n thumbsUpTitle: 'Thumbs up',\n thumbsDownTitle: 'Thumbs down',\n copyTitle: 'Click here to copy response to clipboard.',\n codeCopiedText: 'Copied!',\n widget: {\n chatWidgetContainer: null,\n chatWidgetStateName: null,\n chatHistorySection: null,\n showHistoryButton: null,\n closeHistoryButton: null,\n newChatButton: null,\n toggleButtonSelector: null,\n resetSizeButtonSelector: null,\n dragHandleSelector: '.ai-chat-widget-header',\n enableDragging: true,\n enableResizing: true,\n persistLayout: true,\n defaultWidth: null,\n defaultHeight: null,\n minWidth: 320,\n minHeight: 420\n },\n messageTemplate: `\n \n `,\n indicatorTemplate: `\n${highlighted}' + escaped + '
';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '' + escaped + '
';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n // Update the existing message\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? ''\n : '';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement\n ? this.inputElement.getAttribute('data-profile-id')\n : null;\n },\n setSessionId(sessionId) {\n if (!this.inputElement) {\n return;\n }\n\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.rejectPendingSessionRequest('Session was reset.');\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onSessionReset === 'function') {\n widgetBehavior.onSessionReset(this, config);\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.requestNewSession(profileId).catch(err => console.error(err));\n },\n async ensureSessionForDocuments(profileId) {\n var sessionId = this.getSessionId();\n if (sessionId) {\n return sessionId;\n }\n\n if (!profileId || !this.connection) {\n return null;\n }\n\n return await this.requestNewSession(profileId);\n },\n requestNewSession(profileId) {\n if (this.pendingSessionPromise) {\n return this.pendingSessionPromise;\n }\n\n if (!profileId || !this.connection) {\n return Promise.resolve(null);\n }\n\n this.pendingSessionPromise = new Promise((resolve, reject) => {\n this.pendingSessionResolver = resolve;\n this.pendingSessionRejector = reject;\n this.pendingSessionTimeoutId = window.setTimeout(() => {\n this.rejectPendingSessionRequest('Timed out while creating a chat session.');\n }, 15000);\n });\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => {\n this.rejectPendingSessionRequest(err);\n });\n\n return this.pendingSessionPromise;\n },\n resolvePendingSessionRequest(sessionId) {\n if (this.pendingSessionResolver) {\n this.pendingSessionResolver(sessionId);\n }\n\n this.clearPendingSessionRequest();\n },\n rejectPendingSessionRequest(error) {\n if (this.pendingSessionRejector) {\n this.pendingSessionRejector(error);\n }\n\n this.clearPendingSessionRequest();\n },\n clearPendingSessionRequest() {\n if (this.pendingSessionTimeoutId) {\n window.clearTimeout(this.pendingSessionTimeoutId);\n }\n\n this.pendingSessionPromise = null;\n this.pendingSessionResolver = null;\n this.pendingSessionRejector = null;\n this.pendingSessionTimeoutId = null;\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n\n if (!this.inputElement || !this.buttonElement || !this.chatContainer || !this.placeholder) {\n console.error('AI chat app could not initialize because one or more required elements were not found.', {\n inputElementSelector: config.inputElementSelector,\n sendButtonElementSelector: config.sendButtonElementSelector,\n chatContainerElementSelector: config.chatContainerElementSelector,\n placeholderElementSelector: config.placeholderElementSelector\n });\n\n return false;\n }\n\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n\n return true;\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n if (sessionId && this.getSessionId() === sessionId) {\n this.resolvePendingSessionRequest(sessionId);\n }\n\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n this.resolvePendingSessionRequest(sessionId);\n\n if (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {\n widgetBehavior.onSessionInitialized(this, sessionId, config);\n }\n },\n getSessionId() {\n let sessionId = this.inputElement\n ? this.inputElement.getAttribute('data-session-id')\n : null;\n\n if (!sessionId && widgetBehavior && typeof widgetBehavior.resolveSessionId === 'function') {\n sessionId = widgetBehavior.resolveSessionId(this, config);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Keep feedback icons as simple span-based Font Awesome markup so\n // later state updates do not depend on i2svg replacement.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('span');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('span');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() {\n this.renderDocumentBar();\n if (widgetBehavior && typeof widgetBehavior.onDocumentsChanged === 'function') {\n widgetBehavior.onDocumentsChanged(this, this.documents, config);\n }\n },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isDocumentOperationPending() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n const isInitialized = this.initializeApp();\n if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {\n widgetBehavior.onMounted(this, config);\n }\n\n this.$nextTick(() => {\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\n });\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onBeforeUnmount === 'function') {\n widgetBehavior.onBeforeUnmount(this, config);\n }\n },\n template: config.messageTemplate\n };\n\n const app = Vue.createApp(appDefinition).mount(config.appElementSelector);\n\n if (widgetBehavior && typeof widgetBehavior.attach === 'function') {\n widgetBehavior.attach(app, config);\n }\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js index 5dab04e7..a3896ba1 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js @@ -1,2 +1,2 @@ -var _excluded=["placeholder"];function _regenerator(){/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */var e,t,n="function"==typeof Symbol?Symbol:{},i=n.iterator||"@@iterator",s=n.toStringTag||"@@toStringTag";function o(n,i,s,o){var c=i&&i.prototype instanceof r?i:r,l=Object.create(c.prototype);return _regeneratorDefine2(l,"_invoke",function(n,i,s){var o,r,c,l=0,u=s||[],d=!1,h={p:0,n:0,v:e,a:f,f:f.bind(e,4),d:function(t,n){return o=t,r=0,c=e,h.n=n,a}};function f(n,i){for(r=n,c=i,t=0;!d&&l&&!s&&t').concat(s,"' + escaped + '
';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '' + escaped + '
';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n // Update the existing message\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? ''\n : '';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement\n ? this.inputElement.getAttribute('data-profile-id')\n : null;\n },\n setSessionId(sessionId) {\n if (!this.inputElement) {\n return;\n }\n\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.rejectPendingSessionRequest('Session was reset.');\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onSessionReset === 'function') {\n widgetBehavior.onSessionReset(this, config);\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.requestNewSession(profileId).catch(err => console.error(err));\n },\n async ensureSessionForDocuments(profileId) {\n var sessionId = this.getSessionId();\n if (sessionId) {\n return sessionId;\n }\n\n if (!profileId || !this.connection) {\n return null;\n }\n\n return await this.requestNewSession(profileId);\n },\n requestNewSession(profileId) {\n if (this.pendingSessionPromise) {\n return this.pendingSessionPromise;\n }\n\n if (!profileId || !this.connection) {\n return Promise.resolve(null);\n }\n\n this.pendingSessionPromise = new Promise((resolve, reject) => {\n this.pendingSessionResolver = resolve;\n this.pendingSessionRejector = reject;\n this.pendingSessionTimeoutId = window.setTimeout(() => {\n this.rejectPendingSessionRequest('Timed out while creating a chat session.');\n }, 15000);\n });\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => {\n this.rejectPendingSessionRequest(err);\n });\n\n return this.pendingSessionPromise;\n },\n resolvePendingSessionRequest(sessionId) {\n if (this.pendingSessionResolver) {\n this.pendingSessionResolver(sessionId);\n }\n\n this.clearPendingSessionRequest();\n },\n rejectPendingSessionRequest(error) {\n if (this.pendingSessionRejector) {\n this.pendingSessionRejector(error);\n }\n\n this.clearPendingSessionRequest();\n },\n clearPendingSessionRequest() {\n if (this.pendingSessionTimeoutId) {\n window.clearTimeout(this.pendingSessionTimeoutId);\n }\n\n this.pendingSessionPromise = null;\n this.pendingSessionResolver = null;\n this.pendingSessionRejector = null;\n this.pendingSessionTimeoutId = null;\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n\n if (!this.inputElement || !this.buttonElement || !this.chatContainer || !this.placeholder) {\n console.error('AI chat app could not initialize because one or more required elements were not found.', {\n inputElementSelector: config.inputElementSelector,\n sendButtonElementSelector: config.sendButtonElementSelector,\n chatContainerElementSelector: config.chatContainerElementSelector,\n placeholderElementSelector: config.placeholderElementSelector\n });\n\n return false;\n }\n\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n\n return true;\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n if (sessionId && this.getSessionId() === sessionId) {\n this.resolvePendingSessionRequest(sessionId);\n }\n\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n this.resolvePendingSessionRequest(sessionId);\n\n if (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {\n widgetBehavior.onSessionInitialized(this, sessionId, config);\n }\n },\n getSessionId() {\n let sessionId = this.inputElement\n ? this.inputElement.getAttribute('data-session-id')\n : null;\n\n if (!sessionId && widgetBehavior && typeof widgetBehavior.resolveSessionId === 'function') {\n sessionId = widgetBehavior.resolveSessionId(this, config);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Keep feedback icons as simple span-based Font Awesome markup so\n // later state updates do not depend on i2svg replacement.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('span');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('span');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() {\n this.renderDocumentBar();\n if (widgetBehavior && typeof widgetBehavior.onDocumentsChanged === 'function') {\n widgetBehavior.onDocumentsChanged(this, this.documents, config);\n }\n },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isDocumentOperationPending() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n const isInitialized = this.initializeApp();\n if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {\n widgetBehavior.onMounted(this, config);\n }\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onBeforeUnmount === 'function') {\n widgetBehavior.onBeforeUnmount(this, config);\n }\n },\n template: config.messageTemplate\n };\n\n const app = Vue.createApp(appDefinition).mount(config.appElementSelector);\n\n if (widgetBehavior && typeof widgetBehavior.attach === 'function') {\n widgetBehavior.attach(app, config);\n }\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]} +{"version":3,"sources":["ai-chat.js"],"names":["_excluded","_regenerator","e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","this","setPrototypeOf","__proto__","displayName","w","m","defineProperty","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","openAIChatManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","codeCopiedText","widget","chatWidgetContainer","chatWidgetStateName","chatHistorySection","showHistoryButton","closeHistoryButton","newChatButton","toggleButtonSelector","resetSizeButtonSelector","dragHandleSelector","enableDragging","enableResizing","persistLayout","defaultWidth","defaultHeight","minWidth","minHeight","messageTemplate","indicatorTemplate","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","refreshFontAwesomeIcons","root","fontAwesome","FontAwesome","nodeType","selector","matches","querySelector","containsFontAwesomePlaceholders","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","getCitationLabel","updateMessagePresentation","message","messageReferences","rawContent","content","citationDisplay","processedContent","keys","citations","citedRefs","filter","_ref6","includes","sort","_ref8","_ref9","b","_step","displayIndex","_iterator","_step$value","placeholder","concat","replaceAll","referenceKey","label","isDownload","err","_i2","_citations","citation","map","_ref10","buildCitationDisplay","displayContent","citationReferences","copyContent","_step2","_iterator2","_step3","_iterator3","trimEnd","buildCopyContent","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","renderChartsInMessage","charts","requestAnimationFrame","_step4","_iterator4","renderChartOnCanvas","chartId","config","canvas","getElementById","Chart","console","warn","offsetParent","__chartConfigs","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","use","extensions","level","start","idx","undefined","tokenizer","extracted","token","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","startIndex","endIndex","json","substring","tryExtractChartMarker","type","raw","renderPendingCharts","configs","_i3","_Object$keys","initialize","instanceConfig","hasWidgetConfig","widgetBehavior","openAIChatWidgetBehavior","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","appDefinition","inputElement","buttonElement","chatContainer","isSessionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","notifications","prompt","documents","existingDocuments","isUploading","isDocumentOperationPending","documentOperationQueue","uploadErrors","isDragOver","documentBar","metricsEnabled","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","pendingSessionPromise","pendingSessionResolver","pendingSessionRejector","pendingSessionTimeoutId","computed","lastAssistantIndex","role","methods","handleBeforeUnload","handleDragOver","sessionDocumentsEnabled","preventDefault","stopPropagation","inputArea","closest","classList","add","handleDragLeave","remove","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","target","queueDocumentOperation","operation","self","nextOperation","_callee","_context","_this","_callee3","filesToUpload","_context3","uploadDocumentUrl","_callee2","sessionId","profileId","formData","response","errorText","uploadError","result","_t","_t2","_context2","getSessionId","getProfileId","ensureSessionForDocuments","fileName","renderDocumentBar","FormData","append","fetch","method","body","ok","extractReadableErrorMessage","initializeSession","uploaded","failed","reloadCurrentSession","removeDocument","doc","_this2","_callee5","_context5","removeDocumentUrl","_callee4","removeError","_t3","_context4","headers","stringify","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","closeButtons","querySelectorAll","j","addEventListener","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","div","fallbackMessage","startsWith","parsed","detail","normalizeAssistantAppearance","appearance","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this3","_callee6","_t4","_context6","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","handleReceiveError","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","replace","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","escaped","responseId","hideTypingIndicator","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","autoCreateSession","startNewSession","onclose","addMessageInternal","_this4","fireEvent","CustomEvent","_message$rawContent","_this5","addMessages","_this6","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","style","display","conversationButtonElement","event","isIndicator","trimmedPrompt","streamMessage","startRecording","_this7","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","subject","Subject","pendingChunk","size","_callee7","uint8Array","base64","_context7","arrayBuffer","reduce","str","byte","String","fromCharCode","btoa","getTracks","track","stop","complete","documentElement","send","updateMicButton","toggleRecording","sessionProfileId","_this8","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i4","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_this8$stream","processReferences","streamingFinished","synthesizeSpeech","_this8$stream2","getServiceDownMessage","_this9","_ref15","_message$rawContent2","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this0","button","isPlaying","Number","iconHtml","toggle","cacheIndex","_this1","_ttsCacheIndex","invoke","toggleMessageTts","_this10","playAudioBlob","_this11","_step5","totalLength","sum","combined","offset","_iterator5","set","blob","Blob","_this12","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","_this13","nextBlob","shift","conversationModeOnAudioEnded","_this14","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this15","updateConversationButton","_conversationSubject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","analyser","freqData","frequencyBinCount","getByteFrequencyData","k","_callee8","_context8","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","element","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","location","origin","searchParams","originalLength","_this16","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this17","setTimeout","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this18","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","rejectPendingSessionRequest","sessionRating","onSessionReset","requestNewSession","_this19","_callee9","_context9","_this20","reject","resolvePendingSessionRequest","clearPendingSessionRequest","initializeApp","_this21","placeholderElementSelector","loadSession","documentBarSelector","className","multiple","allowedExtensions","accept","parentElement","appendChild","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","btn","block","codeEl","clipboard","writeText","copiedText","micButtonElementSelector","conversationButtonElementSelector","force","onSessionInitialized","resolveSessionId","copyResponse","_ref17","_message$copyContent","updateFeedbackIcons","container","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","removeEventListener","watch","handler","onDocumentsChanged","deep","active","mounted","_this22","_callee0","_context0","onMounted","fontAwesomeObserver","beforeUnmount","disconnect","onBeforeUnmount","template","app","Vue","createApp","mount","attach","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.min.js","sourcesContent":["window.openAIChatManager = function () {\n\n // Defaults (can be overridden by instanceConfig)\n var defaultConfig = {\n // UI defaults for generated media\n generatedImageAltText: 'Generated Image',\n generatedImageMaxWidth: 400,\n downloadImageTitle: 'Download image',\n downloadChartTitle: 'Download chart as image',\n downloadChartButtonText: 'Download',\n userLabel: 'You',\n assistantLabel: 'Assistant',\n thumbsUpTitle: 'Thumbs up',\n thumbsDownTitle: 'Thumbs down',\n copyTitle: 'Click here to copy response to clipboard.',\n codeCopiedText: 'Copied!',\n widget: {\n chatWidgetContainer: null,\n chatWidgetStateName: null,\n chatHistorySection: null,\n showHistoryButton: null,\n closeHistoryButton: null,\n newChatButton: null,\n toggleButtonSelector: null,\n resetSizeButtonSelector: null,\n dragHandleSelector: '.ai-chat-widget-header',\n enableDragging: true,\n enableResizing: true,\n persistLayout: true,\n defaultWidth: null,\n defaultHeight: null,\n minWidth: 320,\n minHeight: 420\n },\n messageTemplate: `\n \n `,\n indicatorTemplate: `\n${highlighted}' + escaped + '
';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '' + escaped + '
';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n // Update the existing message\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? ''\n : '';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement\n ? this.inputElement.getAttribute('data-profile-id')\n : null;\n },\n setSessionId(sessionId) {\n if (!this.inputElement) {\n return;\n }\n\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.rejectPendingSessionRequest('Session was reset.');\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onSessionReset === 'function') {\n widgetBehavior.onSessionReset(this, config);\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.requestNewSession(profileId).catch(err => console.error(err));\n },\n async ensureSessionForDocuments(profileId) {\n var sessionId = this.getSessionId();\n if (sessionId) {\n return sessionId;\n }\n\n if (!profileId || !this.connection) {\n return null;\n }\n\n return await this.requestNewSession(profileId);\n },\n requestNewSession(profileId) {\n if (this.pendingSessionPromise) {\n return this.pendingSessionPromise;\n }\n\n if (!profileId || !this.connection) {\n return Promise.resolve(null);\n }\n\n this.pendingSessionPromise = new Promise((resolve, reject) => {\n this.pendingSessionResolver = resolve;\n this.pendingSessionRejector = reject;\n this.pendingSessionTimeoutId = window.setTimeout(() => {\n this.rejectPendingSessionRequest('Timed out while creating a chat session.');\n }, 15000);\n });\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => {\n this.rejectPendingSessionRequest(err);\n });\n\n return this.pendingSessionPromise;\n },\n resolvePendingSessionRequest(sessionId) {\n if (this.pendingSessionResolver) {\n this.pendingSessionResolver(sessionId);\n }\n\n this.clearPendingSessionRequest();\n },\n rejectPendingSessionRequest(error) {\n if (this.pendingSessionRejector) {\n this.pendingSessionRejector(error);\n }\n\n this.clearPendingSessionRequest();\n },\n clearPendingSessionRequest() {\n if (this.pendingSessionTimeoutId) {\n window.clearTimeout(this.pendingSessionTimeoutId);\n }\n\n this.pendingSessionPromise = null;\n this.pendingSessionResolver = null;\n this.pendingSessionRejector = null;\n this.pendingSessionTimeoutId = null;\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n\n if (!this.inputElement || !this.buttonElement || !this.chatContainer || !this.placeholder) {\n console.error('AI chat app could not initialize because one or more required elements were not found.', {\n inputElementSelector: config.inputElementSelector,\n sendButtonElementSelector: config.sendButtonElementSelector,\n chatContainerElementSelector: config.chatContainerElementSelector,\n placeholderElementSelector: config.placeholderElementSelector\n });\n\n return false;\n }\n\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n\n return true;\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n if (sessionId && this.getSessionId() === sessionId) {\n this.resolvePendingSessionRequest(sessionId);\n }\n\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n this.resolvePendingSessionRequest(sessionId);\n\n if (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {\n widgetBehavior.onSessionInitialized(this, sessionId, config);\n }\n },\n getSessionId() {\n let sessionId = this.inputElement\n ? this.inputElement.getAttribute('data-session-id')\n : null;\n\n if (!sessionId && widgetBehavior && typeof widgetBehavior.resolveSessionId === 'function') {\n sessionId = widgetBehavior.resolveSessionId(this, config);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Keep feedback icons as simple span-based Font Awesome markup so\n // later state updates do not depend on i2svg replacement.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('span');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('span');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() {\n this.renderDocumentBar();\n if (widgetBehavior && typeof widgetBehavior.onDocumentsChanged === 'function') {\n widgetBehavior.onDocumentsChanged(this, this.documents, config);\n }\n },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isDocumentOperationPending() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n const isInitialized = this.initializeApp();\n if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {\n widgetBehavior.onMounted(this, config);\n }\n\n this.$nextTick(() => {\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\n });\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n\n if (widgetBehavior && typeof widgetBehavior.onBeforeUnmount === 'function') {\n widgetBehavior.onBeforeUnmount(this, config);\n }\n },\n template: config.messageTemplate\n };\n\n const app = Vue.createApp(appDefinition).mount(config.appElementSelector);\n\n if (widgetBehavior && typeof widgetBehavior.attach === 'function') {\n widgetBehavior.attach(app, config);\n }\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js index d7a6ebd5..8a934f1c 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.js @@ -33,8 +33,8 @@ window.chatInteractionManager = function () { downloadChartButtonText: 'Download', codeCopiedText: 'Copied!', assistantLabel: 'Assistant', - messageTemplate: "\n \n ", - indicatorTemplate: "\n").concat(highlighted, "").concat(highlighted, "${highlighted}' + escaped + '
';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (itemId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '' + escaped + '
';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (itemId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (itemId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (itemId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (itemId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"HistoryCleared\", (itemId) => {\n // Clear messages and show placeholder\n this.messages = [];\n this.showPlaceholder();\n\n // Hide the clear history button since there's no history now\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.add('d-none');\n }\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n this.reloadCurrentInteraction();\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingChatInteractionMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedChatInteractionMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : defaultConfig.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n async sendMessage() {\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // Flush any pending settings save before sending a message\n // to prevent concurrent hub calls that can cause database deadlocks.\n await this.flushPendingSave();\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n // Show the clear history button since we now have prompts\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.remove('d-none');\n }\n\n this.streamMessage(trimmedPrompt);\n this.inputElement.value = '';\n this.prompt = '';\n },\n streamMessage(trimmedPrompt) {\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n var messageIndex = this.messages.length;\n var currentItemId = this.getItemId();\n\n this.stream = this.connection.stream(\"SendMessage\", currentItemId, trimmedPrompt)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n if (chunk.sessionId && !currentItemId) {\n this.setItemId(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n messageIndex = this.messages.length;\n let newMessage = {\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n };\n\n this.messages.push(newMessage);\n message = newMessage;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n return {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Save any settings that were deferred during streaming.\n if (this.settingsDirty) {\n this.debouncedSaveSettings();\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? ''\n : '';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getItemId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.isPlayingAudio && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is currently playing, queue this blob for later.\n if (this.isPlayingAudio && this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n const nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var itemId = this.getItemId();\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"StartConversation\", itemId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, continuation is handled\n // by the persistent stream.\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getItemId() {\n return this.inputElement.getAttribute('data-interaction-id')\n || this.inputElement.getAttribute('data-item-id');\n },\n getSaveIndicatorElement() {\n if (config.saveIndicatorElementSelector) {\n return document.querySelector(config.saveIndicatorElementSelector);\n }\n\n return document.querySelector('[data-chat-interaction-save-indicator]');\n },\n showSaveIndicator(text, className) {\n const indicator = this.getSaveIndicatorElement();\n if (!indicator) {\n return;\n }\n\n indicator.textContent = text || '';\n indicator.className = 'settings-save-indicator ' + (className || 'text-muted');\n\n if (this.saveIndicatorTimeout) {\n clearTimeout(this.saveIndicatorTimeout);\n this.saveIndicatorTimeout = null;\n }\n\n if (!text) {\n return;\n }\n\n this.saveIndicatorTimeout = setTimeout(() => {\n indicator.textContent = '';\n this.saveIndicatorTimeout = null;\n }, 3000);\n },\n clearPendingSettingsSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n },\n getFieldLabel(input) {\n const label = input\n .closest('.mb-3, .col-6, .col, .form-group, .form-floating')\n ?.querySelector('label');\n\n if (!label) {\n return input.dataset.setting || 'This field';\n }\n\n return (label.textContent || '')\n .replace(/\\s+/g, ' ')\n .trim()\n || input.dataset.setting\n || 'This field';\n },\n getValidationFeedbackElement(input) {\n let feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n return feedback;\n }\n\n feedback = document.createElement('div');\n feedback.className = 'invalid-feedback';\n input.insertAdjacentElement('afterend', feedback);\n\n return feedback;\n },\n clearSettingValidationError(input) {\n input.classList.remove('is-invalid');\n input.removeAttribute('aria-invalid');\n\n const feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n feedback.textContent = '';\n }\n },\n setSettingValidationError(input, message) {\n const feedback = this.getValidationFeedbackElement(input);\n input.classList.add('is-invalid');\n input.setAttribute('aria-invalid', 'true');\n feedback.textContent = message;\n },\n getSettingValidationMessage(input) {\n if (!input || input.disabled || input.type !== 'number') {\n return null;\n }\n\n const value = (input.value || '').trim();\n if (!value) {\n return null;\n }\n\n const number = Number(value);\n const fieldLabel = this.getFieldLabel(input);\n\n if (Number.isNaN(number)) {\n return `${fieldLabel} must be a valid number.`;\n }\n\n const min = input.getAttribute('min');\n if (min !== null && number < Number(min)) {\n return `${fieldLabel} must be ${min} or greater.`;\n }\n\n const max = input.getAttribute('max');\n if (max !== null && number > Number(max)) {\n return `${fieldLabel} must be ${max} or less.`;\n }\n\n return null;\n },\n validateSettingInput(input) {\n const message = this.getSettingValidationMessage(input);\n if (!message) {\n this.clearSettingValidationError(input);\n return true;\n }\n\n this.setSettingValidationError(input, message);\n return false;\n },\n validateSettings() {\n let isValid = true;\n\n this.getSettingInputs().forEach(input => {\n isValid = this.validateSettingInput(input) && isValid;\n });\n\n return isValid;\n },\n queueSettingsSave() {\n if (!this.validateSettings()) {\n this.clearPendingSettingsSave();\n this.settingsDirty = false;\n this.showSaveIndicator('Fix errors', 'text-danger');\n return;\n }\n\n this.settingsDirty = true;\n this.showSaveIndicator('Saving...', 'text-warning');\n this.debouncedSaveSettings();\n },\n getSettingInputs() {\n const explicitInputs = document.querySelectorAll('.setting-input[data-setting]');\n if (explicitInputs.length > 0) {\n return explicitInputs;\n }\n\n return document.querySelectorAll(\n 'input[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'select[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'textarea[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"])'\n );\n },\n getSelectedGroupValues(groupName, fallbackSelector) {\n const explicitSelections = document.querySelectorAll(`.capability-checkbox[data-save-group=\"${groupName}\"]:checked, .capability-checkbox[data-group=\"${groupName}\"]:checked`);\n if (explicitSelections.length > 0) {\n const values = [];\n\n explicitSelections.forEach(checkbox => {\n const value = checkbox.getAttribute('data-item-id') || checkbox.value;\n if (value) {\n values.push(value);\n }\n });\n\n return values;\n }\n\n if (!fallbackSelector) {\n return [];\n }\n\n const values = [];\n const checkboxes = document.querySelectorAll(fallbackSelector);\n\n checkboxes.forEach(checkbox => {\n const baseName = checkbox.name.replace('.IsSelected', '.ItemId');\n const hiddenInput = document.querySelector(`input[type=\"hidden\"][name=\"${baseName}\"]`);\n\n if (hiddenInput && hiddenInput.value) {\n values.push(hiddenInput.value);\n }\n });\n\n return values;\n },\n getPromptTemplateSelections() {\n const promptTemplates = [];\n\n document.querySelectorAll('.prompt-template-card').forEach(card => {\n const templateIdInput = card.querySelector('.prompt-template-id-input');\n const promptParametersInput = card.querySelector('.prompt-template-parameters-input');\n const templateId = templateIdInput ? templateIdInput.value : card.getAttribute('data-template-id');\n\n if (!templateId) {\n return;\n }\n\n promptTemplates.push({\n templateId: templateId,\n promptParameters: promptParametersInput ? (promptParametersInput.value || '').trim() : ''\n });\n });\n\n return promptTemplates;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n // Replace existing notification with same type, or add new one.\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var itemId = this.getItemId();\n this.connection.invoke('HandleNotificationAction', itemId, notificationType, actionName)\n .catch(err => console.error('Failed to handle notification action:', err));\n },\n setItemId(itemId) {\n this.inputElement.setAttribute('data-interaction-id', itemId || '');\n this.inputElement.setAttribute('data-item-id', itemId || '');\n },\n resetInteraction() {\n this.setItemId('');\n this.isInteractionStarted = false;\n this.messages = [];\n this.showPlaceholder();\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keyup', event => {\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.inputElement.addEventListener('paste', (e) => {\n // Use setTimeout to allow the paste to complete before checking the value\n setTimeout(() => {\n this.prompt = this.inputElement.value;\n if (this.inputElement.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n }, 0);\n });\n\n this.buttonElement.addEventListener('click', () => {\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');\n\n for (var i = 0; i < chatInteractionItems.length; i++) {\n chatInteractionItems[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var itemId = e.target.getAttribute('data-interaction-id');\n\n if (!itemId) {\n console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');\n return;\n }\n\n this.loadInteraction(itemId);\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n document.addEventListener('input', event => {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('change', event => {\n if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n }\n\n this.queueSettingsSave();\n return;\n }\n\n if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('click', event => {\n if (!event.target.closest('.prompt-template-add-btn, .remove-prompt-template-btn')) {\n return;\n }\n\n setTimeout(() => {\n this.queueSettingsSave();\n }, 0);\n });\n\n // Add event listener for clear history button\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.addEventListener('click', () => {\n const itemId = clearHistoryBtn.getAttribute('data-interaction-id');\n if (itemId) {\n this.clearHistory(itemId);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n },\n loadInteraction(itemId) {\n this.connection.invoke(\"LoadInteraction\", itemId).catch(err => console.error(err));\n },\n reloadCurrentInteraction() {\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n },\n clearHistory(itemId) {\n const self = this;\n const clearHistoryConfirmed = () => {\n // Cancel any active stream before clearing history.\n if (self.stream) {\n self.stream.dispose();\n self.stream = null;\n self.hideTypingIndicator();\n self.streamingFinished();\n }\n\n self.connection.invoke(\"ClearHistory\", itemId)\n .catch(err => console.error('Error clearing history:', err));\n };\n\n if (typeof confirmDialog === 'function') {\n confirmDialog({\n title: config.clearHistoryTitle,\n message: config.clearHistoryMessage,\n okText: config.clearHistoryOkText,\n cancelText: config.clearHistoryCancelText,\n callback: function (confirmed) {\n if (confirmed) {\n clearHistoryConfirmed();\n }\n }\n });\n\n return;\n }\n\n if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {\n clearHistoryConfirmed();\n }\n },\n debouncedSaveSettings() {\n // Clear any existing timeout to reset the debounce timer\n this.clearPendingSettingsSave();\n\n // Don't save while streaming — it will be saved when streaming completes.\n if (this.stream) {\n return;\n }\n\n // Set a new timeout to save after 850ms of no changes\n this.saveSettingsTimeout = setTimeout(() => {\n if (this.settingsDirty) {\n this.saveSettings();\n this.settingsDirty = false;\n }\n this.saveSettingsTimeout = null;\n }, 850);\n },\n getSelectedToolNames() {\n return this.getSelectedGroupValues(\n 'toolNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Tools[\"]:checked'\n );\n },\n getSelectedMcpConnectionIds() {\n return this.getSelectedGroupValues(\n 'mcpConnectionIds',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Connections[\"]:checked'\n );\n },\n getSelectedA2AConnectionIds() {\n return this.getSelectedGroupValues('a2aConnectionIds');\n },\n getSelectedAgentNames() {\n return this.getSelectedGroupValues(\n 'agentNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Agents[\"]:checked'\n );\n },\n saveSettings() {\n const itemId = this.getItemId();\n if (!itemId) {\n return Promise.resolve();\n }\n\n if (!this.validateSettings()) {\n this.showSaveIndicator('Fix errors', 'text-danger');\n return Promise.resolve();\n }\n\n const settings = {};\n\n // Collect all form inputs with the \"ChatInteraction.\" prefix generically.\n // This avoids coupling the JS to specific field names — new fields added by\n // any module are automatically included.\n const inputs = this.getSettingInputs();\n\n inputs.forEach(input => {\n const key = input.dataset.setting\n || ((input.name || '').replace('ChatInteraction.', '').replace(/^[A-Z]/, match => match.toLowerCase()));\n\n if (!key) {\n return;\n }\n\n if (input.type === 'checkbox') {\n settings[key] = input.checked;\n } else if (input.type === 'number') {\n settings[key] = input.value ? parseFloat(input.value) : null;\n } else {\n settings[key] = input.value || null;\n }\n });\n\n // Add tool, MCP connection, and agent collections (special handling).\n settings.toolNames = this.getSelectedToolNames();\n settings.mcpConnectionIds = this.getSelectedMcpConnectionIds();\n settings.a2aConnectionIds = this.getSelectedA2AConnectionIds();\n settings.agentNames = this.getSelectedAgentNames();\n\n const promptTemplates = this.getPromptTemplateSelections();\n if (promptTemplates.length > 0) {\n settings.promptTemplates = promptTemplates;\n settings.promptTemplateIds = promptTemplates.map(template => template.templateId);\n }\n\n return this.connection.invoke(\"SaveSettings\", itemId, settings)\n .catch(err => {\n console.error('Error saving settings:', err);\n this.showSaveIndicator('Save failed', 'text-danger');\n });\n },\n flushPendingSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n\n if (this.settingsDirty) {\n this.settingsDirty = false;\n return this.saveSettings();\n }\n\n return Promise.resolve();\n },\n initializeInteraction(itemId, force) {\n if (this.isInteractionStarted && !force) {\n return;\n }\n this.fireEvent(new CustomEvent(\"initializingChatInteraction\", { detail: { itemId: itemId } }));\n this.setItemId(itemId);\n this.isInteractionStarted = true;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var itemId = this.getItemId();\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", itemId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n }\n },\n watch: {\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n },\n template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\nwindow.chatInteractionDocumentManager = function () {\n const managerStateKey = '__chatInteractionDocumentManagerState';\n\n function normalizeDocumentInfo(document) {\n if (!document || typeof document !== 'object') {\n return null;\n }\n\n return {\n documentId: document.documentId || document.DocumentId || '',\n fileName: document.fileName || document.FileName || '',\n fileSize: document.fileSize || document.FileSize || 0\n };\n }\n\n function formatFileSize(bytes) {\n if (!bytes || bytes < 1024) {\n return (bytes || 0) + ' B';\n }\n\n if (bytes < 1024 * 1024) {\n return (bytes / 1024).toFixed(1) + ' KB';\n }\n\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n }\n\n function getDocumentKey(fileName, fileSize) {\n return ((fileName || '').trim().toLowerCase()) + '::' + (fileSize || 0);\n }\n\n function isDuplicateFile(file, knownKeys) {\n return knownKeys.has(getDocumentKey(file.name, file.size));\n }\n\n function getDocumentsFromDom(container) {\n if (!container) {\n return [];\n }\n\n return Array.from(container.querySelectorAll('[data-chat-document-id]'))\n .map(element => normalizeDocumentInfo({\n documentId: element.dataset.chatDocumentId,\n fileName: element.dataset.chatDocumentName,\n fileSize: Number(element.dataset.chatDocumentSize || 0)\n }))\n .filter(document => document && document.documentId);\n }\n\n function initialize(config) {\n if (!config || !config.itemId) {\n return;\n }\n\n const fileInput = document.getElementById('chat-doc-upload');\n const documentsList = document.getElementById('chat-documents-list');\n const status = document.getElementById('chat-doc-upload-status');\n const progressContainer = document.getElementById('chat-doc-upload-progress');\n const progressBar = document.getElementById('chat-doc-upload-progress-bar');\n const uploadQueue = document.getElementById('chat-doc-upload-queue');\n\n if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {\n return;\n }\n\n const previousState = fileInput[managerStateKey];\n if (previousState && typeof previousState.dispose === 'function') {\n previousState.dispose();\n }\n\n let interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n if (interactionDocuments.length === 0) {\n interactionDocuments = getDocumentsFromDom(documentsList);\n }\n\n let uploadItems = [];\n let isUploadingDocuments = false;\n\n function createTextElement(tagName, className, text) {\n const element = document.createElement(tagName);\n if (className) {\n element.className = className;\n }\n\n element.textContent = text;\n return element;\n }\n\n function renderDocuments() {\n documentsList.innerHTML = '';\n\n if (interactionDocuments.length === 0) {\n documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));\n return;\n }\n\n interactionDocuments.forEach(documentInfo => {\n const row = window.document.createElement('div');\n row.className = 'd-flex justify-content-between align-items-start gap-2 border rounded px-2 py-2 bg-white chat-document-row';\n row.dataset.chatDocumentId = documentInfo.documentId;\n row.dataset.chatDocumentName = documentInfo.fileName;\n row.dataset.chatDocumentSize = documentInfo.fileSize;\n\n const details = window.document.createElement('div');\n details.className = 'me-2 min-w-0';\n\n const name = createTextElement('div', 'fw-semibold small', documentInfo.fileName || 'Document');\n const icon = window.document.createElement('i');\n icon.className = 'bi bi-file-earmark-text me-1';\n name.prepend(icon);\n\n const size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));\n\n details.appendChild(name);\n details.appendChild(size);\n\n const removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', ' Remove');\n removeButton.type = 'button';\n removeButton.dataset.documentId = documentInfo.documentId;\n const removeIcon = window.document.createElement('i');\n removeIcon.className = 'bi bi-trash';\n removeButton.prepend(removeIcon);\n removeButton.addEventListener('click', () => removeDocument(documentInfo.documentId));\n\n row.appendChild(details);\n row.appendChild(removeButton);\n documentsList.appendChild(row);\n });\n }\n\n function showUploadStatus(message, cssClass) {\n if (!message) {\n status.textContent = '';\n status.className = 'small mt-2 d-none';\n return;\n }\n\n status.textContent = message;\n status.className = 'small mt-2 ' + (cssClass || 'text-muted');\n }\n\n function showUploadProgress(progress, message, cssClass) {\n if (progress === null || progress === undefined) {\n progressContainer.className = 'progress mt-2 d-none';\n progressContainer.setAttribute('aria-valuenow', '0');\n progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';\n progressBar.style.width = '0%';\n progressBar.textContent = '0%';\n return;\n }\n\n const roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));\n progressContainer.className = 'progress mt-2';\n progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());\n progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');\n progressBar.style.width = roundedProgress + '%';\n progressBar.textContent = message || (roundedProgress + '%');\n }\n\n function getUploadStatePresentation(state) {\n switch (state) {\n case 'uploaded':\n return { label: 'Uploaded', badgeClass: 'text-bg-success', progressClass: 'bg-success' };\n case 'failed':\n return { label: 'Failed', badgeClass: 'text-bg-danger', progressClass: 'bg-danger' };\n case 'uploading':\n return { label: 'Uploading', badgeClass: 'text-bg-warning', progressClass: 'bg-warning progress-bar-striped progress-bar-animated' };\n default:\n return { label: 'Queued', badgeClass: 'text-bg-secondary', progressClass: 'bg-secondary progress-bar-striped progress-bar-animated' };\n }\n }\n\n function formatUploadMessage(item) {\n if (item.status === 'failed' && item.error) {\n return item.error;\n }\n\n if (item.status === 'uploaded') {\n return 'Upload completed successfully.';\n }\n\n if (item.status === 'uploading') {\n return item.progress + '% uploaded';\n }\n\n return 'Waiting to upload...';\n }\n\n function renderUploadQueue() {\n uploadQueue.innerHTML = '';\n\n uploadItems.forEach(item => {\n const presentation = getUploadStatePresentation(item.status);\n const card = document.createElement('div');\n card.className = 'border rounded px-2 py-2 bg-white';\n\n const header = document.createElement('div');\n header.className = 'd-flex justify-content-between align-items-start gap-2';\n\n const fileDetails = document.createElement('div');\n fileDetails.className = 'flex-grow-1 min-w-0';\n fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));\n fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));\n\n const badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);\n\n header.appendChild(fileDetails);\n header.appendChild(badge);\n\n const progress = document.createElement('div');\n progress.className = 'progress mt-2';\n progress.setAttribute('role', 'progressbar');\n progress.setAttribute('aria-valuemin', '0');\n progress.setAttribute('aria-valuemax', '100');\n progress.setAttribute('aria-valuenow', item.progress.toString());\n\n const progressState = document.createElement('div');\n progressState.className = 'progress-bar ' + presentation.progressClass;\n progressState.style.width = item.progress + '%';\n progressState.textContent = item.progress + '%';\n progress.appendChild(progressState);\n\n const message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));\n\n card.appendChild(header);\n card.appendChild(progress);\n card.appendChild(message);\n uploadQueue.appendChild(card);\n });\n }\n\n function createUploadItem(file, index) {\n return {\n id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),\n fileName: file.name,\n fileSize: file.size,\n status: 'queued',\n progress: 0,\n error: null\n };\n }\n\n function updateUploadItem(itemId, updates) {\n uploadItems = uploadItems.map(item => item.id === itemId ? Object.assign({}, item, updates) : item);\n renderUploadQueue();\n }\n\n function removeUploadItems(predicate) {\n uploadItems = uploadItems.filter(item => !predicate(item));\n renderUploadQueue();\n }\n\n function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('chatInteractionId', config.itemId);\n formData.append('files', file);\n\n const xhr = new XMLHttpRequest();\n xhr.open('POST', config.uploadDocumentUrl, true);\n\n xhr.upload.addEventListener('progress', event => {\n if (!event.lengthComputable) {\n return;\n }\n\n const fileProgress = Math.round((event.loaded / event.total) * 100);\n updateUploadItem(itemIdToUpdate, {\n status: 'uploading',\n progress: fileProgress\n });\n\n const overallProgress = ((fileIndex + (event.loaded / event.total)) / totalFiles) * 100;\n showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (error) {\n reject(new Error('Upload failed: invalid server response.'));\n }\n\n return;\n }\n\n reject(new Error((xhr.responseText || 'Upload failed.').trim()));\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Upload failed. Please check your connection and try again.'));\n });\n\n xhr.send(formData);\n });\n }\n\n async function uploadDocuments(files) {\n if (!config.uploadDocumentUrl || !files || files.length === 0) {\n return;\n }\n\n if (isUploadingDocuments) {\n showUploadStatus('A document upload is already in progress.', 'text-warning');\n return;\n }\n\n isUploadingDocuments = true;\n\n const filesToUpload = [];\n const duplicateItems = [];\n const knownDocumentKeys = new Set(interactionDocuments.map(document => getDocumentKey(document.fileName, document.fileSize)));\n\n Array.from(files).forEach(file => {\n if (isDuplicateFile(file, knownDocumentKeys)) {\n duplicateItems.push(file);\n return;\n }\n\n knownDocumentKeys.add(getDocumentKey(file.name, file.size));\n filesToUpload.push(file);\n });\n\n if (duplicateItems.length > 0) {\n uploadItems = uploadItems.concat(duplicateItems.map((file, index) => Object.assign(createUploadItem(file, index), {\n status: 'failed',\n progress: 100,\n error: 'This document is already attached.'\n })));\n renderUploadQueue();\n }\n\n if (filesToUpload.length === 0) {\n isUploadingDocuments = false;\n showUploadStatus(duplicateItems.map(file => file.name + ': This document is already attached.').join(' | '), 'text-warning');\n showUploadProgress(null);\n return;\n }\n\n const pendingItems = filesToUpload.map(createUploadItem);\n uploadItems = uploadItems.concat(pendingItems);\n renderUploadQueue();\n showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');\n fileInput.disabled = true;\n\n try {\n let uploadedCount = 0;\n const failedUploads = duplicateItems.map(file => file.name + ': This document is already attached.');\n\n for (let i = 0; i < filesToUpload.length; i++) {\n const file = filesToUpload[i];\n const pendingItem = pendingItems[i];\n\n updateUploadItem(pendingItem.id, {\n status: 'uploading',\n progress: 0,\n error: null\n });\n\n showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');\n\n try {\n const result = await uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);\n const uploaded = (Array.isArray(result.uploaded) ? result.uploaded : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n const failed = Array.isArray(result.failed) ? result.failed : [];\n\n if (uploaded.length > 0) {\n uploadedCount += uploaded.length;\n interactionDocuments = interactionDocuments.concat(uploaded);\n updateUploadItem(pendingItem.id, {\n status: 'uploaded',\n progress: 100,\n error: null\n });\n } else {\n const missingUploadMessage = failed.length > 0\n ? failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ')\n : 'The server did not confirm that the file was uploaded.';\n if (failed.length === 0) {\n failedUploads.push(missingUploadMessage);\n }\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: missingUploadMessage\n });\n }\n\n if (failed.length > 0) {\n const failedMessage = failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ');\n failedUploads.push(failedMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: failedMessage\n });\n }\n } catch (error) {\n const errorMessage = error && error.message\n ? error.message\n : 'Upload failed. Please try again.';\n console.error('Upload failed:', error);\n failedUploads.push(file.name + ': ' + errorMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: pendingItem.progress || 0,\n error: errorMessage\n });\n }\n }\n\n renderDocuments();\n\n if (failedUploads.length > 0) {\n removeUploadItems(item => item.status === 'uploaded');\n showUploadStatus(\n (uploadedCount > 0 ? ('Uploaded ' + uploadedCount + ' document(s). ') : '') + failedUploads.join(' | '),\n uploadedCount > 0 ? 'text-warning' : 'text-danger');\n showUploadProgress(null);\n return;\n }\n\n removeUploadItems(() => true);\n showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');\n showUploadProgress(null);\n } catch (error) {\n console.error('Upload failed:', error);\n showUploadStatus('Upload failed. Please try again.', 'text-danger');\n showUploadProgress(null);\n } finally {\n isUploadingDocuments = false;\n fileInput.disabled = false;\n fileInput.value = '';\n }\n }\n\n async function removeDocument(documentId) {\n if (!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?')) {\n return;\n }\n\n try {\n const response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n itemId: config.itemId,\n documentId: documentId\n })\n });\n\n if (!response.ok) {\n console.error('Failed to remove document:', await response.text());\n showUploadStatus('Failed to remove document.', 'text-danger');\n return;\n }\n\n const result = await response.json();\n const serverDocuments = (Array.isArray(result.documents) ? result.documents : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n interactionDocuments = serverDocuments.length > 0\n ? serverDocuments\n : interactionDocuments.filter(document => document.documentId !== documentId);\n renderDocuments();\n showUploadStatus('Document removed.', 'text-success');\n } catch (error) {\n console.error('Remove failed:', error);\n showUploadStatus('Failed to remove document.', 'text-danger');\n }\n }\n\n const onFileInputChange = event => {\n const selectedFiles = event.target.files ? Array.from(event.target.files) : [];\n uploadDocuments(selectedFiles);\n };\n\n fileInput.addEventListener('change', onFileInputChange);\n fileInput[managerStateKey] = {\n dispose: () => {\n fileInput.removeEventListener('change', onFileInputChange);\n }\n };\n\n renderDocuments();\n renderUploadQueue();\n showUploadStatus(null);\n showUploadProgress(null);\n }\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]} +{"version":3,"sources":["chat-interaction.js"],"names":["e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","setPrototypeOf","__proto__","displayName","_regenerator","w","m","defineProperty","_regeneratorDefine","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","chatInteractionManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","codeCopiedText","assistantLabel","messageTemplate","indicatorTemplate","untitledText","clearHistoryTitle","clearHistoryMessage","clearHistoryOkText","clearHistoryCancelText","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","containsFontAwesomePlaceholders","root","nodeType","selector","matches","querySelector","refreshFontAwesomeIcons","fontAwesome","FontAwesome","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","getCitationLabel","buildCitationDisplay","content","processedContent","messageReferences","keys","citations","citedRefs","filter","_ref6","_ref7","includes","sort","_ref8","_ref9","_ref0","_ref1","b","displayIndex","_iterator","_step","_step$value","placeholder","concat","replaceAll","referenceKey","label","isDownload","err","_i2","_citations","citation","map","_ref10","_excluded","buildCopyContent","copyContent","_iterator2","_step2","_iterator3","_step3","trimEnd","updateMessagePresentation","message","rawContent","citationDisplay","displayContent","citationReferences","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","__chartConfigs","createChartHtml","chartId","use","extensions","level","start","idx","undefined","tokenizer","extracted","tryExtractChartMarker","startIndex","type","raw","substring","endIndex","json","token","config","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","renderChartsInMessage","charts","requestAnimationFrame","_iterator4","_step4","canvas","getElementById","Chart","console","warn","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","initialize","instanceConfig","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","app","Vue","createApp","inputElement","buttonElement","chatContainer","isInteractionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","prompt","initialFieldValues","Map","settingsDirty","saveSettingsTimeout","saveIndicatorTimeout","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","conversationModeEnabled","conversationButton","isConversationMode","notifications","notificationDismissTimers","computed","lastAssistantIndex","role","methods","handleBeforeUnload","startConnection","_this","_callee","_t","_context","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","initializeInteraction","itemId","titleInput","msg","addMessage","$nextTick","historyItem","showSaveIndicator","stopRecording","isFinal","_conversationPartialTranscript","escaped","replace","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","messageId","responseId","appearance","hideTypingIndicator","j","msgIndex","newMessage","id","normalizeAssistantAppearance","base64Audio","contentType","binaryString","atob","bytes","Uint8Array","charCodeAt","playCollectedAudio","showPlaceholder","clearHistoryBtn","classList","add","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","reloadCurrentInteraction","onclose","addMessageInternal","_this2","fireEvent","CustomEvent","detail","_this3","_message$rawContent","remove","event","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","isIndicator","sendMessage","_this4","_callee2","trimmedPrompt","_context2","flushPendingSave","streamMessage","_this5","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentItemId","getItemId","subscribe","chunk","sessionId","setItemId","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","complete","_this5$stream","processReferences","streamingFinished","synthesizeSpeech","_this5$stream2","getServiceDownMessage","_this6","_ref11","_message$rawContent2","stopIcon","getAttribute","replaceChildren","RETURN_DOM_FRAGMENT","startIcon","icons","querySelectorAll","debouncedSaveSettings","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this7","buttons","button","buttonIndex","Number","isPlaying","iconHtml","toggle","setAttribute","cacheIndex","_this8","_ttsCacheIndex","invoke","toggleMessageTts","_this9","playAudioBlob","_this0","totalLength","reduce","sum","combined","offset","_iterator5","_step5","set","blob","Blob","_this1","URL","createObjectURL","audio","Audio","addEventListener","revokeObjectURL","playNextInQueue","play","_this10","nextBlob","shift","conversationModeOnAudioEnded","_this11","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this12","updateConversationButton","navigator","mediaDevices","getUserMedia","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","_conversationSubject","Subject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","micSource","createMediaStreamSource","connect","pendingChunk","analyser","interruptVolumeThreshold","size","freqData","frequencyBinCount","getByteFrequencyData","k","avg","_callee3","uint8Array","base64","_context3","arrayBuffer","str","byte","String","fromCharCode","btoa","getTracks","track","stop","documentElement","send","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","originalLength","removedCount","_this13","setTimeout","scrollTop","scrollHeight","clientHeight","handleUserInput","target","getSaveIndicatorElement","saveIndicatorElementSelector","className","_this14","indicator","clearTimeout","clearPendingSettingsSave","getFieldLabel","input","_input$closest","closest","dataset","setting","getValidationFeedbackElement","feedback","nextElementSibling","contains","insertAdjacentElement","clearSettingValidationError","removeAttribute","setSettingValidationError","getSettingValidationMessage","disabled","number","fieldLabel","isNaN","min","max","validateSettingInput","validateSettings","_this15","isValid","getSettingInputs","queueSettingsSave","explicitInputs","getSelectedGroupValues","groupName","fallbackSelector","explicitSelections","values","checkbox","checkboxes","baseName","hiddenInput","getPromptTemplateSelections","promptTemplates","card","templateIdInput","promptParametersInput","templateId","promptParameters","clearNotificationDismiss","findIndex","splice","scheduleNotificationDismiss","_this16","timerId","dismissNotification","handleNotificationAction","actionName","resetInteraction","initializeApp","_this17","placeholderElementSelector","loadInteraction","threshold","atBottom","shiftKey","click","lastMsg","pop","chatInteractionItems","getElementsByClassName","preventDefault","btn","block","codeEl","clipboard","writeText","copiedText","clearHistory","micButtonElementSelector","style","display","toggleRecording","conversationButtonElementSelector","self","clearHistoryConfirmed","confirmDialog","okText","cancelText","callback","confirmed","confirm","_this18","saveSettings","getSelectedToolNames","getSelectedMcpConnectionIds","getSelectedA2AConnectionIds","getSelectedAgentNames","_this19","settings","inputs","match","checked","parseFloat","toolNames","mcpConnectionIds","a2aConnectionIds","agentNames","promptTemplateIds","template","force","copyResponse","_ref13","_message$copyContent","startRecording","_this20","subject","_callee4","_context4","updateMicButton","watch","active","mounted","_this21","_callee5","_context5","$el","fontAwesomeObserver","beforeUnmount","removeEventListener","disconnect","mount","chatInteractionDocumentManager","managerStateKey","normalizeDocumentInfo","documentId","DocumentId","fileName","FileName","fileSize","FileSize","formatFileSize","toFixed","getDocumentKey","isDuplicateFile","file","knownKeys","has","getDocumentsFromDom","container","element","chatDocumentId","chatDocumentName","chatDocumentSize","fileInput","documentsList","status","progressContainer","progressBar","uploadQueue","previousState","interactionDocuments","existingDocuments","uploadItems","isUploadingDocuments","createTextElement","tagName","renderDocuments","appendChild","documentInfo","row","details","prepend","removeButton","removeIcon","removeDocument","showUploadStatus","showUploadProgress","progress","width","roundedProgress","round","getUploadStatePresentation","state","badgeClass","progressClass","formatUploadMessage","item","renderUploadQueue","presentation","header","fileDetails","badge","progressState","createUploadItem","lastModified","Date","now","updateUploadItem","updates","removeUploadItems","predicate","uploadSingleDocument","itemIdToUpdate","fileIndex","totalFiles","reject","formData","FormData","append","xhr","XMLHttpRequest","open","uploadDocumentUrl","upload","lengthComputable","fileProgress","loaded","total","overallProgress","responseText","Error","uploadDocuments","_x","_uploadDocuments","_callee6","files","filesToUpload","duplicateItems","knownDocumentKeys","pendingItems","uploadedCount","failedUploads","pendingItem","result","uploaded","failed","missingUploadMessage","failedMessage","errorMessage","_t2","_t3","_context6","Set","join","entry","_x2","_removeDocument","_callee7","response","serverDocuments","_t4","_t5","_context7","removeDocumentUrl","fetch","method","headers","body","stringify","ok","documents","onFileInputChange","selectedFiles","download","toDataURL","img","startsWith","res","removeChild"],"mappings":"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","file":"chat-interaction.js","sourcesContent":["window.chatInteractionManager = function () {\n\n // Defaults (can be overridden by instanceConfig)\n var defaultConfig = {\n // UI defaults for generated media\n generatedImageAltText: 'Generated Image',\n generatedImageMaxWidth: 400,\n downloadImageTitle: 'Download image',\n downloadChartTitle: 'Download chart as image',\n downloadChartButtonText: 'Download',\n codeCopiedText: 'Copied!',\n assistantLabel: 'Assistant',\n\n messageTemplate: `\n \n `,\n indicatorTemplate: `\n${highlighted}' + escaped + '
';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (itemId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '' + escaped + '
';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (itemId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (itemId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (itemId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (itemId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"HistoryCleared\", (itemId) => {\n // Clear messages and show placeholder\n this.messages = [];\n this.showPlaceholder();\n\n // Hide the clear history button since there's no history now\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.add('d-none');\n }\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n this.reloadCurrentInteraction();\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingChatInteractionMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedChatInteractionMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : defaultConfig.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n async sendMessage() {\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // Flush any pending settings save before sending a message\n // to prevent concurrent hub calls that can cause database deadlocks.\n await this.flushPendingSave();\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n // Show the clear history button since we now have prompts\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.remove('d-none');\n }\n\n this.streamMessage(trimmedPrompt);\n this.inputElement.value = '';\n this.prompt = '';\n },\n streamMessage(trimmedPrompt) {\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n var messageIndex = this.messages.length;\n var currentItemId = this.getItemId();\n\n this.stream = this.connection.stream(\"SendMessage\", currentItemId, trimmedPrompt)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n if (chunk.sessionId && !currentItemId) {\n this.setItemId(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n messageIndex = this.messages.length;\n let newMessage = {\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n };\n\n this.messages.push(newMessage);\n message = newMessage;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n return {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Save any settings that were deferred during streaming.\n if (this.settingsDirty) {\n this.debouncedSaveSettings();\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? ''\n : '';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getItemId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.isPlayingAudio && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is currently playing, queue this blob for later.\n if (this.isPlayingAudio && this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n const nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var itemId = this.getItemId();\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"StartConversation\", itemId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, continuation is handled\n // by the persistent stream.\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getItemId() {\n return this.inputElement.getAttribute('data-interaction-id')\n || this.inputElement.getAttribute('data-item-id');\n },\n getSaveIndicatorElement() {\n if (config.saveIndicatorElementSelector) {\n return document.querySelector(config.saveIndicatorElementSelector);\n }\n\n return document.querySelector('[data-chat-interaction-save-indicator]');\n },\n showSaveIndicator(text, className) {\n const indicator = this.getSaveIndicatorElement();\n if (!indicator) {\n return;\n }\n\n indicator.textContent = text || '';\n indicator.className = 'settings-save-indicator ' + (className || 'text-muted');\n\n if (this.saveIndicatorTimeout) {\n clearTimeout(this.saveIndicatorTimeout);\n this.saveIndicatorTimeout = null;\n }\n\n if (!text) {\n return;\n }\n\n this.saveIndicatorTimeout = setTimeout(() => {\n indicator.textContent = '';\n this.saveIndicatorTimeout = null;\n }, 3000);\n },\n clearPendingSettingsSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n },\n getFieldLabel(input) {\n const label = input\n .closest('.mb-3, .col-6, .col, .form-group, .form-floating')\n ?.querySelector('label');\n\n if (!label) {\n return input.dataset.setting || 'This field';\n }\n\n return (label.textContent || '')\n .replace(/\\s+/g, ' ')\n .trim()\n || input.dataset.setting\n || 'This field';\n },\n getValidationFeedbackElement(input) {\n let feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n return feedback;\n }\n\n feedback = document.createElement('div');\n feedback.className = 'invalid-feedback';\n input.insertAdjacentElement('afterend', feedback);\n\n return feedback;\n },\n clearSettingValidationError(input) {\n input.classList.remove('is-invalid');\n input.removeAttribute('aria-invalid');\n\n const feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n feedback.textContent = '';\n }\n },\n setSettingValidationError(input, message) {\n const feedback = this.getValidationFeedbackElement(input);\n input.classList.add('is-invalid');\n input.setAttribute('aria-invalid', 'true');\n feedback.textContent = message;\n },\n getSettingValidationMessage(input) {\n if (!input || input.disabled || input.type !== 'number') {\n return null;\n }\n\n const value = (input.value || '').trim();\n if (!value) {\n return null;\n }\n\n const number = Number(value);\n const fieldLabel = this.getFieldLabel(input);\n\n if (Number.isNaN(number)) {\n return `${fieldLabel} must be a valid number.`;\n }\n\n const min = input.getAttribute('min');\n if (min !== null && number < Number(min)) {\n return `${fieldLabel} must be ${min} or greater.`;\n }\n\n const max = input.getAttribute('max');\n if (max !== null && number > Number(max)) {\n return `${fieldLabel} must be ${max} or less.`;\n }\n\n return null;\n },\n validateSettingInput(input) {\n const message = this.getSettingValidationMessage(input);\n if (!message) {\n this.clearSettingValidationError(input);\n return true;\n }\n\n this.setSettingValidationError(input, message);\n return false;\n },\n validateSettings() {\n let isValid = true;\n\n this.getSettingInputs().forEach(input => {\n isValid = this.validateSettingInput(input) && isValid;\n });\n\n return isValid;\n },\n queueSettingsSave() {\n if (!this.validateSettings()) {\n this.clearPendingSettingsSave();\n this.settingsDirty = false;\n this.showSaveIndicator('Fix errors', 'text-danger');\n return;\n }\n\n this.settingsDirty = true;\n this.showSaveIndicator('Saving...', 'text-warning');\n this.debouncedSaveSettings();\n },\n getSettingInputs() {\n const explicitInputs = document.querySelectorAll('.setting-input[data-setting]');\n if (explicitInputs.length > 0) {\n return explicitInputs;\n }\n\n return document.querySelectorAll(\n 'input[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'select[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'textarea[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"])'\n );\n },\n getSelectedGroupValues(groupName, fallbackSelector) {\n const explicitSelections = document.querySelectorAll(`.capability-checkbox[data-save-group=\"${groupName}\"]:checked, .capability-checkbox[data-group=\"${groupName}\"]:checked`);\n if (explicitSelections.length > 0) {\n const values = [];\n\n explicitSelections.forEach(checkbox => {\n const value = checkbox.getAttribute('data-item-id') || checkbox.value;\n if (value) {\n values.push(value);\n }\n });\n\n return values;\n }\n\n if (!fallbackSelector) {\n return [];\n }\n\n const values = [];\n const checkboxes = document.querySelectorAll(fallbackSelector);\n\n checkboxes.forEach(checkbox => {\n const baseName = checkbox.name.replace('.IsSelected', '.ItemId');\n const hiddenInput = document.querySelector(`input[type=\"hidden\"][name=\"${baseName}\"]`);\n\n if (hiddenInput && hiddenInput.value) {\n values.push(hiddenInput.value);\n }\n });\n\n return values;\n },\n getPromptTemplateSelections() {\n const promptTemplates = [];\n\n document.querySelectorAll('.prompt-template-card').forEach(card => {\n const templateIdInput = card.querySelector('.prompt-template-id-input');\n const promptParametersInput = card.querySelector('.prompt-template-parameters-input');\n const templateId = templateIdInput ? templateIdInput.value : card.getAttribute('data-template-id');\n\n if (!templateId) {\n return;\n }\n\n promptTemplates.push({\n templateId: templateId,\n promptParameters: promptParametersInput ? (promptParametersInput.value || '').trim() : ''\n });\n });\n\n return promptTemplates;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n // Replace existing notification with same type, or add new one.\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var itemId = this.getItemId();\n this.connection.invoke('HandleNotificationAction', itemId, notificationType, actionName)\n .catch(err => console.error('Failed to handle notification action:', err));\n },\n setItemId(itemId) {\n this.inputElement.setAttribute('data-interaction-id', itemId || '');\n this.inputElement.setAttribute('data-item-id', itemId || '');\n },\n resetInteraction() {\n this.setItemId('');\n this.isInteractionStarted = false;\n this.messages = [];\n this.showPlaceholder();\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keyup', event => {\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.inputElement.addEventListener('paste', (e) => {\n // Use setTimeout to allow the paste to complete before checking the value\n setTimeout(() => {\n this.prompt = this.inputElement.value;\n if (this.inputElement.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n }, 0);\n });\n\n this.buttonElement.addEventListener('click', () => {\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');\n\n for (var i = 0; i < chatInteractionItems.length; i++) {\n chatInteractionItems[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var itemId = e.target.getAttribute('data-interaction-id');\n\n if (!itemId) {\n console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');\n return;\n }\n\n this.loadInteraction(itemId);\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n document.addEventListener('input', event => {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('change', event => {\n if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n }\n\n this.queueSettingsSave();\n return;\n }\n\n if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('click', event => {\n if (!event.target.closest('.prompt-template-add-btn, .remove-prompt-template-btn')) {\n return;\n }\n\n setTimeout(() => {\n this.queueSettingsSave();\n }, 0);\n });\n\n // Add event listener for clear history button\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.addEventListener('click', () => {\n const itemId = clearHistoryBtn.getAttribute('data-interaction-id');\n if (itemId) {\n this.clearHistory(itemId);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n },\n loadInteraction(itemId) {\n this.connection.invoke(\"LoadInteraction\", itemId).catch(err => console.error(err));\n },\n reloadCurrentInteraction() {\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n },\n clearHistory(itemId) {\n const self = this;\n const clearHistoryConfirmed = () => {\n // Cancel any active stream before clearing history.\n if (self.stream) {\n self.stream.dispose();\n self.stream = null;\n self.hideTypingIndicator();\n self.streamingFinished();\n }\n\n self.connection.invoke(\"ClearHistory\", itemId)\n .catch(err => console.error('Error clearing history:', err));\n };\n\n if (typeof confirmDialog === 'function') {\n confirmDialog({\n title: config.clearHistoryTitle,\n message: config.clearHistoryMessage,\n okText: config.clearHistoryOkText,\n cancelText: config.clearHistoryCancelText,\n callback: function (confirmed) {\n if (confirmed) {\n clearHistoryConfirmed();\n }\n }\n });\n\n return;\n }\n\n if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {\n clearHistoryConfirmed();\n }\n },\n debouncedSaveSettings() {\n // Clear any existing timeout to reset the debounce timer\n this.clearPendingSettingsSave();\n\n // Don't save while streaming — it will be saved when streaming completes.\n if (this.stream) {\n return;\n }\n\n // Set a new timeout to save after 850ms of no changes\n this.saveSettingsTimeout = setTimeout(() => {\n if (this.settingsDirty) {\n this.saveSettings();\n this.settingsDirty = false;\n }\n this.saveSettingsTimeout = null;\n }, 850);\n },\n getSelectedToolNames() {\n return this.getSelectedGroupValues(\n 'toolNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Tools[\"]:checked'\n );\n },\n getSelectedMcpConnectionIds() {\n return this.getSelectedGroupValues(\n 'mcpConnectionIds',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Connections[\"]:checked'\n );\n },\n getSelectedA2AConnectionIds() {\n return this.getSelectedGroupValues('a2aConnectionIds');\n },\n getSelectedAgentNames() {\n return this.getSelectedGroupValues(\n 'agentNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Agents[\"]:checked'\n );\n },\n saveSettings() {\n const itemId = this.getItemId();\n if (!itemId) {\n return Promise.resolve();\n }\n\n if (!this.validateSettings()) {\n this.showSaveIndicator('Fix errors', 'text-danger');\n return Promise.resolve();\n }\n\n const settings = {};\n\n // Collect all form inputs with the \"ChatInteraction.\" prefix generically.\n // This avoids coupling the JS to specific field names — new fields added by\n // any module are automatically included.\n const inputs = this.getSettingInputs();\n\n inputs.forEach(input => {\n const key = input.dataset.setting\n || ((input.name || '').replace('ChatInteraction.', '').replace(/^[A-Z]/, match => match.toLowerCase()));\n\n if (!key) {\n return;\n }\n\n if (input.type === 'checkbox') {\n settings[key] = input.checked;\n } else if (input.type === 'number') {\n settings[key] = input.value ? parseFloat(input.value) : null;\n } else {\n settings[key] = input.value || null;\n }\n });\n\n // Add tool, MCP connection, and agent collections (special handling).\n settings.toolNames = this.getSelectedToolNames();\n settings.mcpConnectionIds = this.getSelectedMcpConnectionIds();\n settings.a2aConnectionIds = this.getSelectedA2AConnectionIds();\n settings.agentNames = this.getSelectedAgentNames();\n\n const promptTemplates = this.getPromptTemplateSelections();\n if (promptTemplates.length > 0) {\n settings.promptTemplates = promptTemplates;\n settings.promptTemplateIds = promptTemplates.map(template => template.templateId);\n }\n\n return this.connection.invoke(\"SaveSettings\", itemId, settings)\n .catch(err => {\n console.error('Error saving settings:', err);\n this.showSaveIndicator('Save failed', 'text-danger');\n });\n },\n flushPendingSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n\n if (this.settingsDirty) {\n this.settingsDirty = false;\n return this.saveSettings();\n }\n\n return Promise.resolve();\n },\n initializeInteraction(itemId, force) {\n if (this.isInteractionStarted && !force) {\n return;\n }\n this.fireEvent(new CustomEvent(\"initializingChatInteraction\", { detail: { itemId: itemId } }));\n this.setItemId(itemId);\n this.isInteractionStarted = true;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var itemId = this.getItemId();\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", itemId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n }\n },\n watch: {\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n\n this.$nextTick(() => {\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\n });\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n },\n template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\nwindow.chatInteractionDocumentManager = function () {\n const managerStateKey = '__chatInteractionDocumentManagerState';\n\n function normalizeDocumentInfo(document) {\n if (!document || typeof document !== 'object') {\n return null;\n }\n\n return {\n documentId: document.documentId || document.DocumentId || '',\n fileName: document.fileName || document.FileName || '',\n fileSize: document.fileSize || document.FileSize || 0\n };\n }\n\n function formatFileSize(bytes) {\n if (!bytes || bytes < 1024) {\n return (bytes || 0) + ' B';\n }\n\n if (bytes < 1024 * 1024) {\n return (bytes / 1024).toFixed(1) + ' KB';\n }\n\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n }\n\n function getDocumentKey(fileName, fileSize) {\n return ((fileName || '').trim().toLowerCase()) + '::' + (fileSize || 0);\n }\n\n function isDuplicateFile(file, knownKeys) {\n return knownKeys.has(getDocumentKey(file.name, file.size));\n }\n\n function getDocumentsFromDom(container) {\n if (!container) {\n return [];\n }\n\n return Array.from(container.querySelectorAll('[data-chat-document-id]'))\n .map(element => normalizeDocumentInfo({\n documentId: element.dataset.chatDocumentId,\n fileName: element.dataset.chatDocumentName,\n fileSize: Number(element.dataset.chatDocumentSize || 0)\n }))\n .filter(document => document && document.documentId);\n }\n\n function initialize(config) {\n if (!config || !config.itemId) {\n return;\n }\n\n const fileInput = document.getElementById('chat-doc-upload');\n const documentsList = document.getElementById('chat-documents-list');\n const status = document.getElementById('chat-doc-upload-status');\n const progressContainer = document.getElementById('chat-doc-upload-progress');\n const progressBar = document.getElementById('chat-doc-upload-progress-bar');\n const uploadQueue = document.getElementById('chat-doc-upload-queue');\n\n if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {\n return;\n }\n\n const previousState = fileInput[managerStateKey];\n if (previousState && typeof previousState.dispose === 'function') {\n previousState.dispose();\n }\n\n let interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n if (interactionDocuments.length === 0) {\n interactionDocuments = getDocumentsFromDom(documentsList);\n }\n\n let uploadItems = [];\n let isUploadingDocuments = false;\n\n function createTextElement(tagName, className, text) {\n const element = document.createElement(tagName);\n if (className) {\n element.className = className;\n }\n\n element.textContent = text;\n return element;\n }\n\n function renderDocuments() {\n documentsList.innerHTML = '';\n\n if (interactionDocuments.length === 0) {\n documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));\n return;\n }\n\n interactionDocuments.forEach(documentInfo => {\n const row = window.document.createElement('div');\n row.className = 'd-flex justify-content-between align-items-start gap-2 border rounded px-2 py-2 bg-white chat-document-row';\n row.dataset.chatDocumentId = documentInfo.documentId;\n row.dataset.chatDocumentName = documentInfo.fileName;\n row.dataset.chatDocumentSize = documentInfo.fileSize;\n\n const details = window.document.createElement('div');\n details.className = 'me-2 min-w-0';\n\n const name = createTextElement('div', 'fw-semibold small', documentInfo.fileName || 'Document');\n const icon = window.document.createElement('i');\n icon.className = 'bi bi-file-earmark-text me-1';\n name.prepend(icon);\n\n const size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));\n\n details.appendChild(name);\n details.appendChild(size);\n\n const removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', ' Remove');\n removeButton.type = 'button';\n removeButton.dataset.documentId = documentInfo.documentId;\n const removeIcon = window.document.createElement('i');\n removeIcon.className = 'bi bi-trash';\n removeButton.prepend(removeIcon);\n removeButton.addEventListener('click', () => removeDocument(documentInfo.documentId));\n\n row.appendChild(details);\n row.appendChild(removeButton);\n documentsList.appendChild(row);\n });\n }\n\n function showUploadStatus(message, cssClass) {\n if (!message) {\n status.textContent = '';\n status.className = 'small mt-2 d-none';\n return;\n }\n\n status.textContent = message;\n status.className = 'small mt-2 ' + (cssClass || 'text-muted');\n }\n\n function showUploadProgress(progress, message, cssClass) {\n if (progress === null || progress === undefined) {\n progressContainer.className = 'progress mt-2 d-none';\n progressContainer.setAttribute('aria-valuenow', '0');\n progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';\n progressBar.style.width = '0%';\n progressBar.textContent = '0%';\n return;\n }\n\n const roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));\n progressContainer.className = 'progress mt-2';\n progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());\n progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');\n progressBar.style.width = roundedProgress + '%';\n progressBar.textContent = message || (roundedProgress + '%');\n }\n\n function getUploadStatePresentation(state) {\n switch (state) {\n case 'uploaded':\n return { label: 'Uploaded', badgeClass: 'text-bg-success', progressClass: 'bg-success' };\n case 'failed':\n return { label: 'Failed', badgeClass: 'text-bg-danger', progressClass: 'bg-danger' };\n case 'uploading':\n return { label: 'Uploading', badgeClass: 'text-bg-warning', progressClass: 'bg-warning progress-bar-striped progress-bar-animated' };\n default:\n return { label: 'Queued', badgeClass: 'text-bg-secondary', progressClass: 'bg-secondary progress-bar-striped progress-bar-animated' };\n }\n }\n\n function formatUploadMessage(item) {\n if (item.status === 'failed' && item.error) {\n return item.error;\n }\n\n if (item.status === 'uploaded') {\n return 'Upload completed successfully.';\n }\n\n if (item.status === 'uploading') {\n return item.progress + '% uploaded';\n }\n\n return 'Waiting to upload...';\n }\n\n function renderUploadQueue() {\n uploadQueue.innerHTML = '';\n\n uploadItems.forEach(item => {\n const presentation = getUploadStatePresentation(item.status);\n const card = document.createElement('div');\n card.className = 'border rounded px-2 py-2 bg-white';\n\n const header = document.createElement('div');\n header.className = 'd-flex justify-content-between align-items-start gap-2';\n\n const fileDetails = document.createElement('div');\n fileDetails.className = 'flex-grow-1 min-w-0';\n fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));\n fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));\n\n const badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);\n\n header.appendChild(fileDetails);\n header.appendChild(badge);\n\n const progress = document.createElement('div');\n progress.className = 'progress mt-2';\n progress.setAttribute('role', 'progressbar');\n progress.setAttribute('aria-valuemin', '0');\n progress.setAttribute('aria-valuemax', '100');\n progress.setAttribute('aria-valuenow', item.progress.toString());\n\n const progressState = document.createElement('div');\n progressState.className = 'progress-bar ' + presentation.progressClass;\n progressState.style.width = item.progress + '%';\n progressState.textContent = item.progress + '%';\n progress.appendChild(progressState);\n\n const message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));\n\n card.appendChild(header);\n card.appendChild(progress);\n card.appendChild(message);\n uploadQueue.appendChild(card);\n });\n }\n\n function createUploadItem(file, index) {\n return {\n id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),\n fileName: file.name,\n fileSize: file.size,\n status: 'queued',\n progress: 0,\n error: null\n };\n }\n\n function updateUploadItem(itemId, updates) {\n uploadItems = uploadItems.map(item => item.id === itemId ? Object.assign({}, item, updates) : item);\n renderUploadQueue();\n }\n\n function removeUploadItems(predicate) {\n uploadItems = uploadItems.filter(item => !predicate(item));\n renderUploadQueue();\n }\n\n function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('chatInteractionId', config.itemId);\n formData.append('files', file);\n\n const xhr = new XMLHttpRequest();\n xhr.open('POST', config.uploadDocumentUrl, true);\n\n xhr.upload.addEventListener('progress', event => {\n if (!event.lengthComputable) {\n return;\n }\n\n const fileProgress = Math.round((event.loaded / event.total) * 100);\n updateUploadItem(itemIdToUpdate, {\n status: 'uploading',\n progress: fileProgress\n });\n\n const overallProgress = ((fileIndex + (event.loaded / event.total)) / totalFiles) * 100;\n showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (error) {\n reject(new Error('Upload failed: invalid server response.'));\n }\n\n return;\n }\n\n reject(new Error((xhr.responseText || 'Upload failed.').trim()));\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Upload failed. Please check your connection and try again.'));\n });\n\n xhr.send(formData);\n });\n }\n\n async function uploadDocuments(files) {\n if (!config.uploadDocumentUrl || !files || files.length === 0) {\n return;\n }\n\n if (isUploadingDocuments) {\n showUploadStatus('A document upload is already in progress.', 'text-warning');\n return;\n }\n\n isUploadingDocuments = true;\n\n const filesToUpload = [];\n const duplicateItems = [];\n const knownDocumentKeys = new Set(interactionDocuments.map(document => getDocumentKey(document.fileName, document.fileSize)));\n\n Array.from(files).forEach(file => {\n if (isDuplicateFile(file, knownDocumentKeys)) {\n duplicateItems.push(file);\n return;\n }\n\n knownDocumentKeys.add(getDocumentKey(file.name, file.size));\n filesToUpload.push(file);\n });\n\n if (duplicateItems.length > 0) {\n uploadItems = uploadItems.concat(duplicateItems.map((file, index) => Object.assign(createUploadItem(file, index), {\n status: 'failed',\n progress: 100,\n error: 'This document is already attached.'\n })));\n renderUploadQueue();\n }\n\n if (filesToUpload.length === 0) {\n isUploadingDocuments = false;\n showUploadStatus(duplicateItems.map(file => file.name + ': This document is already attached.').join(' | '), 'text-warning');\n showUploadProgress(null);\n return;\n }\n\n const pendingItems = filesToUpload.map(createUploadItem);\n uploadItems = uploadItems.concat(pendingItems);\n renderUploadQueue();\n showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');\n fileInput.disabled = true;\n\n try {\n let uploadedCount = 0;\n const failedUploads = duplicateItems.map(file => file.name + ': This document is already attached.');\n\n for (let i = 0; i < filesToUpload.length; i++) {\n const file = filesToUpload[i];\n const pendingItem = pendingItems[i];\n\n updateUploadItem(pendingItem.id, {\n status: 'uploading',\n progress: 0,\n error: null\n });\n\n showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');\n\n try {\n const result = await uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);\n const uploaded = (Array.isArray(result.uploaded) ? result.uploaded : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n const failed = Array.isArray(result.failed) ? result.failed : [];\n\n if (uploaded.length > 0) {\n uploadedCount += uploaded.length;\n interactionDocuments = interactionDocuments.concat(uploaded);\n updateUploadItem(pendingItem.id, {\n status: 'uploaded',\n progress: 100,\n error: null\n });\n } else {\n const missingUploadMessage = failed.length > 0\n ? failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ')\n : 'The server did not confirm that the file was uploaded.';\n if (failed.length === 0) {\n failedUploads.push(missingUploadMessage);\n }\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: missingUploadMessage\n });\n }\n\n if (failed.length > 0) {\n const failedMessage = failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ');\n failedUploads.push(failedMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: failedMessage\n });\n }\n } catch (error) {\n const errorMessage = error && error.message\n ? error.message\n : 'Upload failed. Please try again.';\n console.error('Upload failed:', error);\n failedUploads.push(file.name + ': ' + errorMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: pendingItem.progress || 0,\n error: errorMessage\n });\n }\n }\n\n renderDocuments();\n\n if (failedUploads.length > 0) {\n removeUploadItems(item => item.status === 'uploaded');\n showUploadStatus(\n (uploadedCount > 0 ? ('Uploaded ' + uploadedCount + ' document(s). ') : '') + failedUploads.join(' | '),\n uploadedCount > 0 ? 'text-warning' : 'text-danger');\n showUploadProgress(null);\n return;\n }\n\n removeUploadItems(() => true);\n showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');\n showUploadProgress(null);\n } catch (error) {\n console.error('Upload failed:', error);\n showUploadStatus('Upload failed. Please try again.', 'text-danger');\n showUploadProgress(null);\n } finally {\n isUploadingDocuments = false;\n fileInput.disabled = false;\n fileInput.value = '';\n }\n }\n\n async function removeDocument(documentId) {\n if (!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?')) {\n return;\n }\n\n try {\n const response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n itemId: config.itemId,\n documentId: documentId\n })\n });\n\n if (!response.ok) {\n console.error('Failed to remove document:', await response.text());\n showUploadStatus('Failed to remove document.', 'text-danger');\n return;\n }\n\n const result = await response.json();\n const serverDocuments = (Array.isArray(result.documents) ? result.documents : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n interactionDocuments = serverDocuments.length > 0\n ? serverDocuments\n : interactionDocuments.filter(document => document.documentId !== documentId);\n renderDocuments();\n showUploadStatus('Document removed.', 'text-success');\n } catch (error) {\n console.error('Remove failed:', error);\n showUploadStatus('Failed to remove document.', 'text-danger');\n }\n }\n\n const onFileInputChange = event => {\n const selectedFiles = event.target.files ? Array.from(event.target.files) : [];\n uploadDocuments(selectedFiles);\n };\n\n fileInput.addEventListener('change', onFileInputChange);\n fileInput[managerStateKey] = {\n dispose: () => {\n fileInput.removeEventListener('change', onFileInputChange);\n }\n };\n\n renderDocuments();\n renderUploadQueue();\n showUploadStatus(null);\n showUploadProgress(null);\n }\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.min.js b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.min.js index 9e37be2c..93c198c8 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.min.js +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/chat-interaction.min.js @@ -1,2 +1,2 @@ -var _excluded=["placeholder"];function _regenerator(){/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */var e,t,n="function"==typeof Symbol?Symbol:{},i=n.iterator||"@@iterator",a=n.toStringTag||"@@toStringTag";function o(n,i,a,o){var c=i&&i.prototype instanceof s?i:s,l=Object.create(c.prototype);return _regeneratorDefine2(l,"_invoke",function(n,i,a){var o,s,c,l=0,u=a||[],d=!1,m={p:0,n:0,v:e,a:h,f:h.bind(e,4),d:function(t,n){return o=t,s=0,c=e,m.n=n,r}};function h(n,i){for(s=n,c=i,t=0;!d&&l&&!a&&t').concat(a,"' + escaped + '
';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (itemId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '' + escaped + '
';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (itemId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (itemId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (itemId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (itemId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"HistoryCleared\", (itemId) => {\n // Clear messages and show placeholder\n this.messages = [];\n this.showPlaceholder();\n\n // Hide the clear history button since there's no history now\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.add('d-none');\n }\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n this.reloadCurrentInteraction();\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingChatInteractionMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedChatInteractionMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : defaultConfig.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n async sendMessage() {\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // Flush any pending settings save before sending a message\n // to prevent concurrent hub calls that can cause database deadlocks.\n await this.flushPendingSave();\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n // Show the clear history button since we now have prompts\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.remove('d-none');\n }\n\n this.streamMessage(trimmedPrompt);\n this.inputElement.value = '';\n this.prompt = '';\n },\n streamMessage(trimmedPrompt) {\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n var messageIndex = this.messages.length;\n var currentItemId = this.getItemId();\n\n this.stream = this.connection.stream(\"SendMessage\", currentItemId, trimmedPrompt)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n if (chunk.sessionId && !currentItemId) {\n this.setItemId(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n messageIndex = this.messages.length;\n let newMessage = {\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n };\n\n this.messages.push(newMessage);\n message = newMessage;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n return {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Save any settings that were deferred during streaming.\n if (this.settingsDirty) {\n this.debouncedSaveSettings();\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? ''\n : '';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getItemId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.isPlayingAudio && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is currently playing, queue this blob for later.\n if (this.isPlayingAudio && this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n const nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var itemId = this.getItemId();\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"StartConversation\", itemId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, continuation is handled\n // by the persistent stream.\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getItemId() {\n return this.inputElement.getAttribute('data-interaction-id')\n || this.inputElement.getAttribute('data-item-id');\n },\n getSaveIndicatorElement() {\n if (config.saveIndicatorElementSelector) {\n return document.querySelector(config.saveIndicatorElementSelector);\n }\n\n return document.querySelector('[data-chat-interaction-save-indicator]');\n },\n showSaveIndicator(text, className) {\n const indicator = this.getSaveIndicatorElement();\n if (!indicator) {\n return;\n }\n\n indicator.textContent = text || '';\n indicator.className = 'settings-save-indicator ' + (className || 'text-muted');\n\n if (this.saveIndicatorTimeout) {\n clearTimeout(this.saveIndicatorTimeout);\n this.saveIndicatorTimeout = null;\n }\n\n if (!text) {\n return;\n }\n\n this.saveIndicatorTimeout = setTimeout(() => {\n indicator.textContent = '';\n this.saveIndicatorTimeout = null;\n }, 3000);\n },\n clearPendingSettingsSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n },\n getFieldLabel(input) {\n const label = input\n .closest('.mb-3, .col-6, .col, .form-group, .form-floating')\n ?.querySelector('label');\n\n if (!label) {\n return input.dataset.setting || 'This field';\n }\n\n return (label.textContent || '')\n .replace(/\\s+/g, ' ')\n .trim()\n || input.dataset.setting\n || 'This field';\n },\n getValidationFeedbackElement(input) {\n let feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n return feedback;\n }\n\n feedback = document.createElement('div');\n feedback.className = 'invalid-feedback';\n input.insertAdjacentElement('afterend', feedback);\n\n return feedback;\n },\n clearSettingValidationError(input) {\n input.classList.remove('is-invalid');\n input.removeAttribute('aria-invalid');\n\n const feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n feedback.textContent = '';\n }\n },\n setSettingValidationError(input, message) {\n const feedback = this.getValidationFeedbackElement(input);\n input.classList.add('is-invalid');\n input.setAttribute('aria-invalid', 'true');\n feedback.textContent = message;\n },\n getSettingValidationMessage(input) {\n if (!input || input.disabled || input.type !== 'number') {\n return null;\n }\n\n const value = (input.value || '').trim();\n if (!value) {\n return null;\n }\n\n const number = Number(value);\n const fieldLabel = this.getFieldLabel(input);\n\n if (Number.isNaN(number)) {\n return `${fieldLabel} must be a valid number.`;\n }\n\n const min = input.getAttribute('min');\n if (min !== null && number < Number(min)) {\n return `${fieldLabel} must be ${min} or greater.`;\n }\n\n const max = input.getAttribute('max');\n if (max !== null && number > Number(max)) {\n return `${fieldLabel} must be ${max} or less.`;\n }\n\n return null;\n },\n validateSettingInput(input) {\n const message = this.getSettingValidationMessage(input);\n if (!message) {\n this.clearSettingValidationError(input);\n return true;\n }\n\n this.setSettingValidationError(input, message);\n return false;\n },\n validateSettings() {\n let isValid = true;\n\n this.getSettingInputs().forEach(input => {\n isValid = this.validateSettingInput(input) && isValid;\n });\n\n return isValid;\n },\n queueSettingsSave() {\n if (!this.validateSettings()) {\n this.clearPendingSettingsSave();\n this.settingsDirty = false;\n this.showSaveIndicator('Fix errors', 'text-danger');\n return;\n }\n\n this.settingsDirty = true;\n this.showSaveIndicator('Saving...', 'text-warning');\n this.debouncedSaveSettings();\n },\n getSettingInputs() {\n const explicitInputs = document.querySelectorAll('.setting-input[data-setting]');\n if (explicitInputs.length > 0) {\n return explicitInputs;\n }\n\n return document.querySelectorAll(\n 'input[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'select[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'textarea[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"])'\n );\n },\n getSelectedGroupValues(groupName, fallbackSelector) {\n const explicitSelections = document.querySelectorAll(`.capability-checkbox[data-save-group=\"${groupName}\"]:checked, .capability-checkbox[data-group=\"${groupName}\"]:checked`);\n if (explicitSelections.length > 0) {\n const values = [];\n\n explicitSelections.forEach(checkbox => {\n const value = checkbox.getAttribute('data-item-id') || checkbox.value;\n if (value) {\n values.push(value);\n }\n });\n\n return values;\n }\n\n if (!fallbackSelector) {\n return [];\n }\n\n const values = [];\n const checkboxes = document.querySelectorAll(fallbackSelector);\n\n checkboxes.forEach(checkbox => {\n const baseName = checkbox.name.replace('.IsSelected', '.ItemId');\n const hiddenInput = document.querySelector(`input[type=\"hidden\"][name=\"${baseName}\"]`);\n\n if (hiddenInput && hiddenInput.value) {\n values.push(hiddenInput.value);\n }\n });\n\n return values;\n },\n getPromptTemplateSelections() {\n const promptTemplates = [];\n\n document.querySelectorAll('.prompt-template-card').forEach(card => {\n const templateIdInput = card.querySelector('.prompt-template-id-input');\n const promptParametersInput = card.querySelector('.prompt-template-parameters-input');\n const templateId = templateIdInput ? templateIdInput.value : card.getAttribute('data-template-id');\n\n if (!templateId) {\n return;\n }\n\n promptTemplates.push({\n templateId: templateId,\n promptParameters: promptParametersInput ? (promptParametersInput.value || '').trim() : ''\n });\n });\n\n return promptTemplates;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n // Replace existing notification with same type, or add new one.\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var itemId = this.getItemId();\n this.connection.invoke('HandleNotificationAction', itemId, notificationType, actionName)\n .catch(err => console.error('Failed to handle notification action:', err));\n },\n setItemId(itemId) {\n this.inputElement.setAttribute('data-interaction-id', itemId || '');\n this.inputElement.setAttribute('data-item-id', itemId || '');\n },\n resetInteraction() {\n this.setItemId('');\n this.isInteractionStarted = false;\n this.messages = [];\n this.showPlaceholder();\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keyup', event => {\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.inputElement.addEventListener('paste', (e) => {\n // Use setTimeout to allow the paste to complete before checking the value\n setTimeout(() => {\n this.prompt = this.inputElement.value;\n if (this.inputElement.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n }, 0);\n });\n\n this.buttonElement.addEventListener('click', () => {\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');\n\n for (var i = 0; i < chatInteractionItems.length; i++) {\n chatInteractionItems[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var itemId = e.target.getAttribute('data-interaction-id');\n\n if (!itemId) {\n console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');\n return;\n }\n\n this.loadInteraction(itemId);\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n document.addEventListener('input', event => {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('change', event => {\n if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n }\n\n this.queueSettingsSave();\n return;\n }\n\n if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('click', event => {\n if (!event.target.closest('.prompt-template-add-btn, .remove-prompt-template-btn')) {\n return;\n }\n\n setTimeout(() => {\n this.queueSettingsSave();\n }, 0);\n });\n\n // Add event listener for clear history button\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.addEventListener('click', () => {\n const itemId = clearHistoryBtn.getAttribute('data-interaction-id');\n if (itemId) {\n this.clearHistory(itemId);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n },\n loadInteraction(itemId) {\n this.connection.invoke(\"LoadInteraction\", itemId).catch(err => console.error(err));\n },\n reloadCurrentInteraction() {\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n },\n clearHistory(itemId) {\n const self = this;\n const clearHistoryConfirmed = () => {\n // Cancel any active stream before clearing history.\n if (self.stream) {\n self.stream.dispose();\n self.stream = null;\n self.hideTypingIndicator();\n self.streamingFinished();\n }\n\n self.connection.invoke(\"ClearHistory\", itemId)\n .catch(err => console.error('Error clearing history:', err));\n };\n\n if (typeof confirmDialog === 'function') {\n confirmDialog({\n title: config.clearHistoryTitle,\n message: config.clearHistoryMessage,\n okText: config.clearHistoryOkText,\n cancelText: config.clearHistoryCancelText,\n callback: function (confirmed) {\n if (confirmed) {\n clearHistoryConfirmed();\n }\n }\n });\n\n return;\n }\n\n if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {\n clearHistoryConfirmed();\n }\n },\n debouncedSaveSettings() {\n // Clear any existing timeout to reset the debounce timer\n this.clearPendingSettingsSave();\n\n // Don't save while streaming — it will be saved when streaming completes.\n if (this.stream) {\n return;\n }\n\n // Set a new timeout to save after 850ms of no changes\n this.saveSettingsTimeout = setTimeout(() => {\n if (this.settingsDirty) {\n this.saveSettings();\n this.settingsDirty = false;\n }\n this.saveSettingsTimeout = null;\n }, 850);\n },\n getSelectedToolNames() {\n return this.getSelectedGroupValues(\n 'toolNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Tools[\"]:checked'\n );\n },\n getSelectedMcpConnectionIds() {\n return this.getSelectedGroupValues(\n 'mcpConnectionIds',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Connections[\"]:checked'\n );\n },\n getSelectedA2AConnectionIds() {\n return this.getSelectedGroupValues('a2aConnectionIds');\n },\n getSelectedAgentNames() {\n return this.getSelectedGroupValues(\n 'agentNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Agents[\"]:checked'\n );\n },\n saveSettings() {\n const itemId = this.getItemId();\n if (!itemId) {\n return Promise.resolve();\n }\n\n if (!this.validateSettings()) {\n this.showSaveIndicator('Fix errors', 'text-danger');\n return Promise.resolve();\n }\n\n const settings = {};\n\n // Collect all form inputs with the \"ChatInteraction.\" prefix generically.\n // This avoids coupling the JS to specific field names — new fields added by\n // any module are automatically included.\n const inputs = this.getSettingInputs();\n\n inputs.forEach(input => {\n const key = input.dataset.setting\n || ((input.name || '').replace('ChatInteraction.', '').replace(/^[A-Z]/, match => match.toLowerCase()));\n\n if (!key) {\n return;\n }\n\n if (input.type === 'checkbox') {\n settings[key] = input.checked;\n } else if (input.type === 'number') {\n settings[key] = input.value ? parseFloat(input.value) : null;\n } else {\n settings[key] = input.value || null;\n }\n });\n\n // Add tool, MCP connection, and agent collections (special handling).\n settings.toolNames = this.getSelectedToolNames();\n settings.mcpConnectionIds = this.getSelectedMcpConnectionIds();\n settings.a2aConnectionIds = this.getSelectedA2AConnectionIds();\n settings.agentNames = this.getSelectedAgentNames();\n\n const promptTemplates = this.getPromptTemplateSelections();\n if (promptTemplates.length > 0) {\n settings.promptTemplates = promptTemplates;\n settings.promptTemplateIds = promptTemplates.map(template => template.templateId);\n }\n\n return this.connection.invoke(\"SaveSettings\", itemId, settings)\n .catch(err => {\n console.error('Error saving settings:', err);\n this.showSaveIndicator('Save failed', 'text-danger');\n });\n },\n flushPendingSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n\n if (this.settingsDirty) {\n this.settingsDirty = false;\n return this.saveSettings();\n }\n\n return Promise.resolve();\n },\n initializeInteraction(itemId, force) {\n if (this.isInteractionStarted && !force) {\n return;\n }\n this.fireEvent(new CustomEvent(\"initializingChatInteraction\", { detail: { itemId: itemId } }));\n this.setItemId(itemId);\n this.isInteractionStarted = true;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var itemId = this.getItemId();\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", itemId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n }\n },\n watch: {\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n },\n template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\nwindow.chatInteractionDocumentManager = function () {\n const managerStateKey = '__chatInteractionDocumentManagerState';\n\n function normalizeDocumentInfo(document) {\n if (!document || typeof document !== 'object') {\n return null;\n }\n\n return {\n documentId: document.documentId || document.DocumentId || '',\n fileName: document.fileName || document.FileName || '',\n fileSize: document.fileSize || document.FileSize || 0\n };\n }\n\n function formatFileSize(bytes) {\n if (!bytes || bytes < 1024) {\n return (bytes || 0) + ' B';\n }\n\n if (bytes < 1024 * 1024) {\n return (bytes / 1024).toFixed(1) + ' KB';\n }\n\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n }\n\n function getDocumentKey(fileName, fileSize) {\n return ((fileName || '').trim().toLowerCase()) + '::' + (fileSize || 0);\n }\n\n function isDuplicateFile(file, knownKeys) {\n return knownKeys.has(getDocumentKey(file.name, file.size));\n }\n\n function getDocumentsFromDom(container) {\n if (!container) {\n return [];\n }\n\n return Array.from(container.querySelectorAll('[data-chat-document-id]'))\n .map(element => normalizeDocumentInfo({\n documentId: element.dataset.chatDocumentId,\n fileName: element.dataset.chatDocumentName,\n fileSize: Number(element.dataset.chatDocumentSize || 0)\n }))\n .filter(document => document && document.documentId);\n }\n\n function initialize(config) {\n if (!config || !config.itemId) {\n return;\n }\n\n const fileInput = document.getElementById('chat-doc-upload');\n const documentsList = document.getElementById('chat-documents-list');\n const status = document.getElementById('chat-doc-upload-status');\n const progressContainer = document.getElementById('chat-doc-upload-progress');\n const progressBar = document.getElementById('chat-doc-upload-progress-bar');\n const uploadQueue = document.getElementById('chat-doc-upload-queue');\n\n if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {\n return;\n }\n\n const previousState = fileInput[managerStateKey];\n if (previousState && typeof previousState.dispose === 'function') {\n previousState.dispose();\n }\n\n let interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n if (interactionDocuments.length === 0) {\n interactionDocuments = getDocumentsFromDom(documentsList);\n }\n\n let uploadItems = [];\n let isUploadingDocuments = false;\n\n function createTextElement(tagName, className, text) {\n const element = document.createElement(tagName);\n if (className) {\n element.className = className;\n }\n\n element.textContent = text;\n return element;\n }\n\n function renderDocuments() {\n documentsList.innerHTML = '';\n\n if (interactionDocuments.length === 0) {\n documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));\n return;\n }\n\n interactionDocuments.forEach(documentInfo => {\n const row = window.document.createElement('div');\n row.className = 'd-flex justify-content-between align-items-start gap-2 border rounded px-2 py-2 bg-white chat-document-row';\n row.dataset.chatDocumentId = documentInfo.documentId;\n row.dataset.chatDocumentName = documentInfo.fileName;\n row.dataset.chatDocumentSize = documentInfo.fileSize;\n\n const details = window.document.createElement('div');\n details.className = 'me-2 min-w-0';\n\n const name = createTextElement('div', 'fw-semibold small', documentInfo.fileName || 'Document');\n const icon = window.document.createElement('i');\n icon.className = 'bi bi-file-earmark-text me-1';\n name.prepend(icon);\n\n const size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));\n\n details.appendChild(name);\n details.appendChild(size);\n\n const removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', ' Remove');\n removeButton.type = 'button';\n removeButton.dataset.documentId = documentInfo.documentId;\n const removeIcon = window.document.createElement('i');\n removeIcon.className = 'bi bi-trash';\n removeButton.prepend(removeIcon);\n removeButton.addEventListener('click', () => removeDocument(documentInfo.documentId));\n\n row.appendChild(details);\n row.appendChild(removeButton);\n documentsList.appendChild(row);\n });\n }\n\n function showUploadStatus(message, cssClass) {\n if (!message) {\n status.textContent = '';\n status.className = 'small mt-2 d-none';\n return;\n }\n\n status.textContent = message;\n status.className = 'small mt-2 ' + (cssClass || 'text-muted');\n }\n\n function showUploadProgress(progress, message, cssClass) {\n if (progress === null || progress === undefined) {\n progressContainer.className = 'progress mt-2 d-none';\n progressContainer.setAttribute('aria-valuenow', '0');\n progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';\n progressBar.style.width = '0%';\n progressBar.textContent = '0%';\n return;\n }\n\n const roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));\n progressContainer.className = 'progress mt-2';\n progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());\n progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');\n progressBar.style.width = roundedProgress + '%';\n progressBar.textContent = message || (roundedProgress + '%');\n }\n\n function getUploadStatePresentation(state) {\n switch (state) {\n case 'uploaded':\n return { label: 'Uploaded', badgeClass: 'text-bg-success', progressClass: 'bg-success' };\n case 'failed':\n return { label: 'Failed', badgeClass: 'text-bg-danger', progressClass: 'bg-danger' };\n case 'uploading':\n return { label: 'Uploading', badgeClass: 'text-bg-warning', progressClass: 'bg-warning progress-bar-striped progress-bar-animated' };\n default:\n return { label: 'Queued', badgeClass: 'text-bg-secondary', progressClass: 'bg-secondary progress-bar-striped progress-bar-animated' };\n }\n }\n\n function formatUploadMessage(item) {\n if (item.status === 'failed' && item.error) {\n return item.error;\n }\n\n if (item.status === 'uploaded') {\n return 'Upload completed successfully.';\n }\n\n if (item.status === 'uploading') {\n return item.progress + '% uploaded';\n }\n\n return 'Waiting to upload...';\n }\n\n function renderUploadQueue() {\n uploadQueue.innerHTML = '';\n\n uploadItems.forEach(item => {\n const presentation = getUploadStatePresentation(item.status);\n const card = document.createElement('div');\n card.className = 'border rounded px-2 py-2 bg-white';\n\n const header = document.createElement('div');\n header.className = 'd-flex justify-content-between align-items-start gap-2';\n\n const fileDetails = document.createElement('div');\n fileDetails.className = 'flex-grow-1 min-w-0';\n fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));\n fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));\n\n const badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);\n\n header.appendChild(fileDetails);\n header.appendChild(badge);\n\n const progress = document.createElement('div');\n progress.className = 'progress mt-2';\n progress.setAttribute('role', 'progressbar');\n progress.setAttribute('aria-valuemin', '0');\n progress.setAttribute('aria-valuemax', '100');\n progress.setAttribute('aria-valuenow', item.progress.toString());\n\n const progressState = document.createElement('div');\n progressState.className = 'progress-bar ' + presentation.progressClass;\n progressState.style.width = item.progress + '%';\n progressState.textContent = item.progress + '%';\n progress.appendChild(progressState);\n\n const message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));\n\n card.appendChild(header);\n card.appendChild(progress);\n card.appendChild(message);\n uploadQueue.appendChild(card);\n });\n }\n\n function createUploadItem(file, index) {\n return {\n id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),\n fileName: file.name,\n fileSize: file.size,\n status: 'queued',\n progress: 0,\n error: null\n };\n }\n\n function updateUploadItem(itemId, updates) {\n uploadItems = uploadItems.map(item => item.id === itemId ? Object.assign({}, item, updates) : item);\n renderUploadQueue();\n }\n\n function removeUploadItems(predicate) {\n uploadItems = uploadItems.filter(item => !predicate(item));\n renderUploadQueue();\n }\n\n function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('chatInteractionId', config.itemId);\n formData.append('files', file);\n\n const xhr = new XMLHttpRequest();\n xhr.open('POST', config.uploadDocumentUrl, true);\n\n xhr.upload.addEventListener('progress', event => {\n if (!event.lengthComputable) {\n return;\n }\n\n const fileProgress = Math.round((event.loaded / event.total) * 100);\n updateUploadItem(itemIdToUpdate, {\n status: 'uploading',\n progress: fileProgress\n });\n\n const overallProgress = ((fileIndex + (event.loaded / event.total)) / totalFiles) * 100;\n showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (error) {\n reject(new Error('Upload failed: invalid server response.'));\n }\n\n return;\n }\n\n reject(new Error((xhr.responseText || 'Upload failed.').trim()));\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Upload failed. Please check your connection and try again.'));\n });\n\n xhr.send(formData);\n });\n }\n\n async function uploadDocuments(files) {\n if (!config.uploadDocumentUrl || !files || files.length === 0) {\n return;\n }\n\n if (isUploadingDocuments) {\n showUploadStatus('A document upload is already in progress.', 'text-warning');\n return;\n }\n\n isUploadingDocuments = true;\n\n const filesToUpload = [];\n const duplicateItems = [];\n const knownDocumentKeys = new Set(interactionDocuments.map(document => getDocumentKey(document.fileName, document.fileSize)));\n\n Array.from(files).forEach(file => {\n if (isDuplicateFile(file, knownDocumentKeys)) {\n duplicateItems.push(file);\n return;\n }\n\n knownDocumentKeys.add(getDocumentKey(file.name, file.size));\n filesToUpload.push(file);\n });\n\n if (duplicateItems.length > 0) {\n uploadItems = uploadItems.concat(duplicateItems.map((file, index) => Object.assign(createUploadItem(file, index), {\n status: 'failed',\n progress: 100,\n error: 'This document is already attached.'\n })));\n renderUploadQueue();\n }\n\n if (filesToUpload.length === 0) {\n isUploadingDocuments = false;\n showUploadStatus(duplicateItems.map(file => file.name + ': This document is already attached.').join(' | '), 'text-warning');\n showUploadProgress(null);\n return;\n }\n\n const pendingItems = filesToUpload.map(createUploadItem);\n uploadItems = uploadItems.concat(pendingItems);\n renderUploadQueue();\n showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');\n fileInput.disabled = true;\n\n try {\n let uploadedCount = 0;\n const failedUploads = duplicateItems.map(file => file.name + ': This document is already attached.');\n\n for (let i = 0; i < filesToUpload.length; i++) {\n const file = filesToUpload[i];\n const pendingItem = pendingItems[i];\n\n updateUploadItem(pendingItem.id, {\n status: 'uploading',\n progress: 0,\n error: null\n });\n\n showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');\n\n try {\n const result = await uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);\n const uploaded = (Array.isArray(result.uploaded) ? result.uploaded : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n const failed = Array.isArray(result.failed) ? result.failed : [];\n\n if (uploaded.length > 0) {\n uploadedCount += uploaded.length;\n interactionDocuments = interactionDocuments.concat(uploaded);\n updateUploadItem(pendingItem.id, {\n status: 'uploaded',\n progress: 100,\n error: null\n });\n } else {\n const missingUploadMessage = failed.length > 0\n ? failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ')\n : 'The server did not confirm that the file was uploaded.';\n if (failed.length === 0) {\n failedUploads.push(missingUploadMessage);\n }\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: missingUploadMessage\n });\n }\n\n if (failed.length > 0) {\n const failedMessage = failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ');\n failedUploads.push(failedMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: failedMessage\n });\n }\n } catch (error) {\n const errorMessage = error && error.message\n ? error.message\n : 'Upload failed. Please try again.';\n console.error('Upload failed:', error);\n failedUploads.push(file.name + ': ' + errorMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: pendingItem.progress || 0,\n error: errorMessage\n });\n }\n }\n\n renderDocuments();\n\n if (failedUploads.length > 0) {\n removeUploadItems(item => item.status === 'uploaded');\n showUploadStatus(\n (uploadedCount > 0 ? ('Uploaded ' + uploadedCount + ' document(s). ') : '') + failedUploads.join(' | '),\n uploadedCount > 0 ? 'text-warning' : 'text-danger');\n showUploadProgress(null);\n return;\n }\n\n removeUploadItems(() => true);\n showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');\n showUploadProgress(null);\n } catch (error) {\n console.error('Upload failed:', error);\n showUploadStatus('Upload failed. Please try again.', 'text-danger');\n showUploadProgress(null);\n } finally {\n isUploadingDocuments = false;\n fileInput.disabled = false;\n fileInput.value = '';\n }\n }\n\n async function removeDocument(documentId) {\n if (!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?')) {\n return;\n }\n\n try {\n const response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n itemId: config.itemId,\n documentId: documentId\n })\n });\n\n if (!response.ok) {\n console.error('Failed to remove document:', await response.text());\n showUploadStatus('Failed to remove document.', 'text-danger');\n return;\n }\n\n const result = await response.json();\n const serverDocuments = (Array.isArray(result.documents) ? result.documents : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n interactionDocuments = serverDocuments.length > 0\n ? serverDocuments\n : interactionDocuments.filter(document => document.documentId !== documentId);\n renderDocuments();\n showUploadStatus('Document removed.', 'text-success');\n } catch (error) {\n console.error('Remove failed:', error);\n showUploadStatus('Failed to remove document.', 'text-danger');\n }\n }\n\n const onFileInputChange = event => {\n const selectedFiles = event.target.files ? Array.from(event.target.files) : [];\n uploadDocuments(selectedFiles);\n };\n\n fileInput.addEventListener('change', onFileInputChange);\n fileInput[managerStateKey] = {\n dispose: () => {\n fileInput.removeEventListener('change', onFileInputChange);\n }\n };\n\n renderDocuments();\n renderUploadQueue();\n showUploadStatus(null);\n showUploadProgress(null);\n }\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]} +{"version":3,"sources":["chat-interaction.js"],"names":["_excluded","_regenerator","e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","this","setPrototypeOf","__proto__","displayName","w","m","defineProperty","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_unsupportedIterableToArray","_nonIterableSpread","Array","from","isArray","_arrayLikeToArray","_objectWithoutProperties","_objectWithoutPropertiesLoose","getOwnPropertySymbols","indexOf","propertyIsEnumerable","hasOwnProperty","_createForOfIteratorHelper","_n","F","s","next","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","chatInteractionManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","codeCopiedText","assistantLabel","messageTemplate","indicatorTemplate","untitledText","clearHistoryTitle","clearHistoryMessage","clearHistoryOkText","clearHistoryCancelText","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","refreshFontAwesomeIcons","root","fontAwesome","FontAwesome","nodeType","selector","matches","querySelector","containsFontAwesomePlaceholders","dom","i2svg","node","observeFontAwesomeIcons","MutationObserver","observer","mutations","forEach","mutation","addedNodes","observe","childList","subtree","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$title","_ref4","_normalized$link","_ref5","_normalized$reference","normalized","assign","index","Index","Text","title","Title","link","Link","referenceType","ReferenceType","isDownloadCitationReference","toLowerCase","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","getCitationLabel","updateMessagePresentation","message","messageReferences","rawContent","content","citationDisplay","processedContent","keys","citations","citedRefs","filter","_ref6","includes","sort","_ref8","_ref9","b","_step","displayIndex","_iterator","_step$value","placeholder","concat","replaceAll","referenceKey","label","isDownload","err","_i2","_citations","citation","map","_ref10","buildCitationDisplay","displayContent","citationReferences","copyContent","_step2","_iterator2","_step3","_iterator3","trimEnd","buildCopyContent","htmlContent","parseMarkdownContent","renderer","marked","Renderer","data","href","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","renderChartsInMessage","charts","requestAnimationFrame","_step4","_iterator4","canvas","getElementById","chartId","Chart","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","config","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","console","error","__chartConfigs","warn","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","use","extensions","level","start","idx","undefined","tokenizer","extracted","token","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","startIndex","endIndex","json","substring","tryExtractChartMarker","type","raw","initialize","instanceConfig","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","Vue","createApp","inputElement","buttonElement","chatContainer","isInteractionStarted","isPlaceholderVisible","isStreaming","isNavigatingAway","autoScroll","stream","messages","prompt","initialFieldValues","Map","settingsDirty","saveSettingsTimeout","saveIndicatorTimeout","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","Math","random","conversationModeEnabled","conversationButton","isConversationMode","notifications","notificationDismissTimers","computed","lastAssistantIndex","role","methods","handleBeforeUnload","startConnection","_this","_callee","_t","_context","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","initializeInteraction","itemId","titleInput","msg","addMessage","$nextTick","historyItem","showSaveIndicator","stopRecording","isFinal","_conversationPartialTranscript","replace","_conversationPartialMessage","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","escaped","messageId","responseId","appearance","hideTypingIndicator","j","msgIndex","newMessage","id","normalizeAssistantAppearance","base64Audio","contentType","binaryString","atob","bytes","Uint8Array","charCodeAt","playCollectedAudio","showPlaceholder","clearHistoryBtn","classList","add","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","reloadCurrentInteraction","onclose","addMessageInternal","_this2","fireEvent","CustomEvent","detail","_message$rawContent","_this3","remove","event","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","isIndicator","sendMessage","_this4","_callee2","trimmedPrompt","_context2","flushPendingSave","streamMessage","_this5","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentItemId","getItemId","subscribe","chunk","sessionId","setItemId","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","complete","_this5$stream","processReferences","streamingFinished","synthesizeSpeech","_this5$stream2","getServiceDownMessage","_this6","_ref11","_message$rawContent2","stopIcon","getAttribute","replaceChildren","RETURN_DOM_FRAGMENT","startIcon","icons","querySelectorAll","debouncedSaveSettings","handleExternalTtsStop","_e$detail","sourceId","updateTtsPlaybackButtons","_this7","button","isPlaying","Number","iconHtml","toggle","setAttribute","cacheIndex","_this8","_ttsCacheIndex","invoke","toggleMessageTts","_this9","playAudioBlob","_this0","_step5","totalLength","reduce","sum","combined","offset","_iterator5","set","blob","Blob","_this1","URL","createObjectURL","audio","Audio","addEventListener","revokeObjectURL","playNextInQueue","play","_this10","nextBlob","shift","conversationModeOnAudioEnded","_this11","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this12","updateConversationButton","navigator","mediaDevices","getUserMedia","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","_conversationSubject","Subject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","pendingChunk","analyser","size","freqData","frequencyBinCount","getByteFrequencyData","k","_callee3","uint8Array","base64","_context3","arrayBuffer","str","byte","String","fromCharCode","btoa","getTracks","track","stop","documentElement","send","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","originalLength","_this13","setTimeout","scrollTop","scrollHeight","clientHeight","handleUserInput","target","getSaveIndicatorElement","saveIndicatorElementSelector","className","_this14","indicator","clearTimeout","clearPendingSettingsSave","getFieldLabel","input","_input$closest","closest","dataset","setting","getValidationFeedbackElement","feedback","nextElementSibling","contains","insertAdjacentElement","clearSettingValidationError","removeAttribute","setSettingValidationError","getSettingValidationMessage","disabled","number","fieldLabel","isNaN","min","max","validateSettingInput","validateSettings","_this15","isValid","getSettingInputs","queueSettingsSave","explicitInputs","getSelectedGroupValues","groupName","fallbackSelector","explicitSelections","values","checkbox","baseName","hiddenInput","getPromptTemplateSelections","promptTemplates","card","templateIdInput","promptParametersInput","templateId","promptParameters","clearNotificationDismiss","findIndex","splice","scheduleNotificationDismiss","_this16","timerId","dismissNotification","handleNotificationAction","actionName","resetInteraction","initializeApp","_this17","placeholderElementSelector","loadInteraction","atBottom","shiftKey","click","lastMsg","pop","chatInteractionItems","getElementsByClassName","preventDefault","btn","block","codeEl","clipboard","writeText","copiedText","clearHistory","micButtonElementSelector","style","display","toggleRecording","conversationButtonElementSelector","self","clearHistoryConfirmed","confirmDialog","confirm","okText","cancelText","callback","confirmed","_this18","saveSettings","getSelectedToolNames","getSelectedMcpConnectionIds","getSelectedA2AConnectionIds","getSelectedAgentNames","_this19","settings","match","checked","parseFloat","toolNames","mcpConnectionIds","a2aConnectionIds","agentNames","promptTemplateIds","template","force","copyResponse","_ref13","_message$copyContent","startRecording","_this20","subject","_callee4","_context4","updateMicButton","watch","active","mounted","_this21","_callee5","_context5","$el","fontAwesomeObserver","beforeUnmount","removeEventListener","disconnect","mount","chatInteractionDocumentManager","managerStateKey","normalizeDocumentInfo","documentId","DocumentId","fileName","FileName","fileSize","FileSize","formatFileSize","toFixed","getDocumentKey","isDuplicateFile","file","knownKeys","has","fileInput","documentsList","status","progressContainer","progressBar","uploadQueue","previousState","container","interactionDocuments","existingDocuments","element","chatDocumentId","chatDocumentName","chatDocumentSize","uploadItems","isUploadingDocuments","onFileInputChange","_x","_uploadDocuments","uploadDocuments","files","renderDocuments","renderUploadQueue","showUploadStatus","showUploadProgress","createTextElement","tagName","documentInfo","row","details","prepend","appendChild","removeButton","removeIcon","_x2","_removeDocument","removeDocument","progress","width","roundedProgress","round","item","presentation","state","badgeClass","progressClass","getUploadStatePresentation","header","fileDetails","badge","progressState","formatUploadMessage","createUploadItem","lastModified","Date","now","updateUploadItem","updates","removeUploadItems","predicate","uploadSingleDocument","itemIdToUpdate","fileIndex","totalFiles","reject","formData","FormData","append","xhr","XMLHttpRequest","open","uploadDocumentUrl","upload","lengthComputable","fileProgress","loaded","total","responseText","Error","_callee6","filesToUpload","duplicateItems","knownDocumentKeys","pendingItems","uploadedCount","failedUploads","pendingItem","result","uploaded","failed","missingUploadMessage","failedMessage","errorMessage","_t2","_t3","_context6","Set","join","entry","_callee7","response","serverDocuments","_t4","_t5","_context7","removeDocumentUrl","fetch","method","headers","body","stringify","ok","documents","download","toDataURL","img","startsWith","res","removeChild"],"mappings":"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","file":"chat-interaction.min.js","sourcesContent":["window.chatInteractionManager = function () {\n\n // Defaults (can be overridden by instanceConfig)\n var defaultConfig = {\n // UI defaults for generated media\n generatedImageAltText: 'Generated Image',\n generatedImageMaxWidth: 400,\n downloadImageTitle: 'Download image',\n downloadChartTitle: 'Download chart as image',\n downloadChartButtonText: 'Download',\n codeCopiedText: 'Copied!',\n assistantLabel: 'Assistant',\n\n messageTemplate: `\n \n `,\n indicatorTemplate: `\n${highlighted}' + escaped + '
';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (itemId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '' + escaped + '
';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (itemId, messageId, token, responseId, references, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n appearance: this.normalizeAssistantAppearance(appearance),\n references: {},\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.rawContent = this._conversationAssistantMessage.content;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (itemId, messageId, references) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));\n updateMessagePresentation(msg, msg.references);\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (itemId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (itemId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"HistoryCleared\", (itemId) => {\n // Clear messages and show placeholder\n this.messages = [];\n this.showPlaceholder();\n\n // Hide the clear history button since there's no history now\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.add('d-none');\n }\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n this.reloadCurrentInteraction();\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingChatInteractionMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedChatInteractionMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n if (message.content) {\n message.rawContent = message.rawContent ?? message.content;\n updateMessagePresentation(message, message.references);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : defaultConfig.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n async sendMessage() {\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // Flush any pending settings save before sending a message\n // to prevent concurrent hub calls that can cause database deadlocks.\n await this.flushPendingSave();\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n // Show the clear history button since we now have prompts\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.classList.remove('d-none');\n }\n\n this.streamMessage(trimmedPrompt);\n this.inputElement.value = '';\n this.prompt = '';\n },\n streamMessage(trimmedPrompt) {\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n var messageIndex = this.messages.length;\n var currentItemId = this.getItemId();\n\n this.stream = this.connection.stream(\"SendMessage\", currentItemId, trimmedPrompt)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n if (chunk.sessionId && !currentItemId) {\n this.setItemId(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n messageIndex = this.messages.length;\n let newMessage = {\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n };\n\n this.messages.push(newMessage);\n message = newMessage;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n content += chunk.content;\n }\n\n message.rawContent = content;\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n return {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n let message = this.messages[messageIndex];\n message.rawContent = message.rawContent ?? message.content ?? '';\n updateMessagePresentation(message, references);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Save any settings that were deferred during streaming.\n if (this.settingsDirty) {\n this.debouncedSaveSettings();\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n updateTtsPlaybackButtons() {\n if (!this.chatContainer) {\n return;\n }\n\n var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');\n\n buttons.forEach(button => {\n var buttonIndex = Number(button.getAttribute('data-tts-message-index'));\n var isPlaying = buttonIndex === this.ttsPlayingMessageIndex;\n var iconHtml = isPlaying\n ? ''\n : '';\n\n button.classList.toggle('tts-playing', isPlaying);\n button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');\n button.replaceChildren(DOMPurify.sanitize(iconHtml, { RETURN_DOM_FRAGMENT: true }));\n });\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getItemId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.isPlayingAudio && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is currently playing, queue this blob for later.\n if (this.isPlayingAudio && this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n const nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.$nextTick(() => this.updateTtsPlaybackButtons());\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var itemId = this.getItemId();\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"StartConversation\", itemId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, continuation is handled\n // by the persistent stream.\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getItemId() {\n return this.inputElement.getAttribute('data-interaction-id')\n || this.inputElement.getAttribute('data-item-id');\n },\n getSaveIndicatorElement() {\n if (config.saveIndicatorElementSelector) {\n return document.querySelector(config.saveIndicatorElementSelector);\n }\n\n return document.querySelector('[data-chat-interaction-save-indicator]');\n },\n showSaveIndicator(text, className) {\n const indicator = this.getSaveIndicatorElement();\n if (!indicator) {\n return;\n }\n\n indicator.textContent = text || '';\n indicator.className = 'settings-save-indicator ' + (className || 'text-muted');\n\n if (this.saveIndicatorTimeout) {\n clearTimeout(this.saveIndicatorTimeout);\n this.saveIndicatorTimeout = null;\n }\n\n if (!text) {\n return;\n }\n\n this.saveIndicatorTimeout = setTimeout(() => {\n indicator.textContent = '';\n this.saveIndicatorTimeout = null;\n }, 3000);\n },\n clearPendingSettingsSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n },\n getFieldLabel(input) {\n const label = input\n .closest('.mb-3, .col-6, .col, .form-group, .form-floating')\n ?.querySelector('label');\n\n if (!label) {\n return input.dataset.setting || 'This field';\n }\n\n return (label.textContent || '')\n .replace(/\\s+/g, ' ')\n .trim()\n || input.dataset.setting\n || 'This field';\n },\n getValidationFeedbackElement(input) {\n let feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n return feedback;\n }\n\n feedback = document.createElement('div');\n feedback.className = 'invalid-feedback';\n input.insertAdjacentElement('afterend', feedback);\n\n return feedback;\n },\n clearSettingValidationError(input) {\n input.classList.remove('is-invalid');\n input.removeAttribute('aria-invalid');\n\n const feedback = input.nextElementSibling;\n if (feedback && feedback.classList.contains('invalid-feedback')) {\n feedback.textContent = '';\n }\n },\n setSettingValidationError(input, message) {\n const feedback = this.getValidationFeedbackElement(input);\n input.classList.add('is-invalid');\n input.setAttribute('aria-invalid', 'true');\n feedback.textContent = message;\n },\n getSettingValidationMessage(input) {\n if (!input || input.disabled || input.type !== 'number') {\n return null;\n }\n\n const value = (input.value || '').trim();\n if (!value) {\n return null;\n }\n\n const number = Number(value);\n const fieldLabel = this.getFieldLabel(input);\n\n if (Number.isNaN(number)) {\n return `${fieldLabel} must be a valid number.`;\n }\n\n const min = input.getAttribute('min');\n if (min !== null && number < Number(min)) {\n return `${fieldLabel} must be ${min} or greater.`;\n }\n\n const max = input.getAttribute('max');\n if (max !== null && number > Number(max)) {\n return `${fieldLabel} must be ${max} or less.`;\n }\n\n return null;\n },\n validateSettingInput(input) {\n const message = this.getSettingValidationMessage(input);\n if (!message) {\n this.clearSettingValidationError(input);\n return true;\n }\n\n this.setSettingValidationError(input, message);\n return false;\n },\n validateSettings() {\n let isValid = true;\n\n this.getSettingInputs().forEach(input => {\n isValid = this.validateSettingInput(input) && isValid;\n });\n\n return isValid;\n },\n queueSettingsSave() {\n if (!this.validateSettings()) {\n this.clearPendingSettingsSave();\n this.settingsDirty = false;\n this.showSaveIndicator('Fix errors', 'text-danger');\n return;\n }\n\n this.settingsDirty = true;\n this.showSaveIndicator('Saving...', 'text-warning');\n this.debouncedSaveSettings();\n },\n getSettingInputs() {\n const explicitInputs = document.querySelectorAll('.setting-input[data-setting]');\n if (explicitInputs.length > 0) {\n return explicitInputs;\n }\n\n return document.querySelectorAll(\n 'input[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'select[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"]), ' +\n 'textarea[name^=\"ChatInteraction.\"]:not([name*=\".Tools[\"]):not([name*=\".Connections[\"])'\n );\n },\n getSelectedGroupValues(groupName, fallbackSelector) {\n const explicitSelections = document.querySelectorAll(`.capability-checkbox[data-save-group=\"${groupName}\"]:checked, .capability-checkbox[data-group=\"${groupName}\"]:checked`);\n if (explicitSelections.length > 0) {\n const values = [];\n\n explicitSelections.forEach(checkbox => {\n const value = checkbox.getAttribute('data-item-id') || checkbox.value;\n if (value) {\n values.push(value);\n }\n });\n\n return values;\n }\n\n if (!fallbackSelector) {\n return [];\n }\n\n const values = [];\n const checkboxes = document.querySelectorAll(fallbackSelector);\n\n checkboxes.forEach(checkbox => {\n const baseName = checkbox.name.replace('.IsSelected', '.ItemId');\n const hiddenInput = document.querySelector(`input[type=\"hidden\"][name=\"${baseName}\"]`);\n\n if (hiddenInput && hiddenInput.value) {\n values.push(hiddenInput.value);\n }\n });\n\n return values;\n },\n getPromptTemplateSelections() {\n const promptTemplates = [];\n\n document.querySelectorAll('.prompt-template-card').forEach(card => {\n const templateIdInput = card.querySelector('.prompt-template-id-input');\n const promptParametersInput = card.querySelector('.prompt-template-parameters-input');\n const templateId = templateIdInput ? templateIdInput.value : card.getAttribute('data-template-id');\n\n if (!templateId) {\n return;\n }\n\n promptTemplates.push({\n templateId: templateId,\n promptParameters: promptParametersInput ? (promptParametersInput.value || '').trim() : ''\n });\n });\n\n return promptTemplates;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n // Replace existing notification with same type, or add new one.\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var idx = this.notifications.findIndex(n => n.type === notification.type);\n if (idx >= 0) {\n this.notifications.splice(idx, 1, notification);\n this.scheduleNotificationDismiss(notification);\n this.scrollToBottom();\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var itemId = this.getItemId();\n this.connection.invoke('HandleNotificationAction', itemId, notificationType, actionName)\n .catch(err => console.error('Failed to handle notification action:', err));\n },\n setItemId(itemId) {\n this.inputElement.setAttribute('data-interaction-id', itemId || '');\n this.inputElement.setAttribute('data-item-id', itemId || '');\n },\n resetInteraction() {\n this.setItemId('');\n this.isInteractionStarted = false;\n this.messages = [];\n this.showPlaceholder();\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keyup', event => {\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.inputElement.addEventListener('paste', (e) => {\n // Use setTimeout to allow the paste to complete before checking the value\n setTimeout(() => {\n this.prompt = this.inputElement.value;\n if (this.inputElement.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n }, 0);\n });\n\n this.buttonElement.addEventListener('click', () => {\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');\n\n for (var i = 0; i < chatInteractionItems.length; i++) {\n chatInteractionItems[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var itemId = e.target.getAttribute('data-interaction-id');\n\n if (!itemId) {\n console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');\n return;\n }\n\n this.loadInteraction(itemId);\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n document.addEventListener('input', event => {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('change', event => {\n if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {\n if (event.target.matches('.setting-input[data-setting]')) {\n this.validateSettingInput(event.target);\n }\n\n this.queueSettingsSave();\n return;\n }\n\n if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {\n this.queueSettingsSave();\n }\n });\n\n document.addEventListener('click', event => {\n if (!event.target.closest('.prompt-template-add-btn, .remove-prompt-template-btn')) {\n return;\n }\n\n setTimeout(() => {\n this.queueSettingsSave();\n }, 0);\n });\n\n // Add event listener for clear history button\n const clearHistoryBtn = document.getElementById('clearHistoryBtn');\n if (clearHistoryBtn) {\n clearHistoryBtn.addEventListener('click', () => {\n const itemId = clearHistoryBtn.getAttribute('data-interaction-id');\n if (itemId) {\n this.clearHistory(itemId);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n },\n loadInteraction(itemId) {\n this.connection.invoke(\"LoadInteraction\", itemId).catch(err => console.error(err));\n },\n reloadCurrentInteraction() {\n const itemId = this.getItemId();\n if (itemId) {\n this.loadInteraction(itemId);\n }\n },\n clearHistory(itemId) {\n const self = this;\n const clearHistoryConfirmed = () => {\n // Cancel any active stream before clearing history.\n if (self.stream) {\n self.stream.dispose();\n self.stream = null;\n self.hideTypingIndicator();\n self.streamingFinished();\n }\n\n self.connection.invoke(\"ClearHistory\", itemId)\n .catch(err => console.error('Error clearing history:', err));\n };\n\n if (typeof confirmDialog === 'function') {\n confirmDialog({\n title: config.clearHistoryTitle,\n message: config.clearHistoryMessage,\n okText: config.clearHistoryOkText,\n cancelText: config.clearHistoryCancelText,\n callback: function (confirmed) {\n if (confirmed) {\n clearHistoryConfirmed();\n }\n }\n });\n\n return;\n }\n\n if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {\n clearHistoryConfirmed();\n }\n },\n debouncedSaveSettings() {\n // Clear any existing timeout to reset the debounce timer\n this.clearPendingSettingsSave();\n\n // Don't save while streaming — it will be saved when streaming completes.\n if (this.stream) {\n return;\n }\n\n // Set a new timeout to save after 850ms of no changes\n this.saveSettingsTimeout = setTimeout(() => {\n if (this.settingsDirty) {\n this.saveSettings();\n this.settingsDirty = false;\n }\n this.saveSettingsTimeout = null;\n }, 850);\n },\n getSelectedToolNames() {\n return this.getSelectedGroupValues(\n 'toolNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Tools[\"]:checked'\n );\n },\n getSelectedMcpConnectionIds() {\n return this.getSelectedGroupValues(\n 'mcpConnectionIds',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Connections[\"]:checked'\n );\n },\n getSelectedA2AConnectionIds() {\n return this.getSelectedGroupValues('a2aConnectionIds');\n },\n getSelectedAgentNames() {\n return this.getSelectedGroupValues(\n 'agentNames',\n 'input[type=\"checkbox\"][name$=\"].IsSelected\"][name^=\"ChatInteraction.Agents[\"]:checked'\n );\n },\n saveSettings() {\n const itemId = this.getItemId();\n if (!itemId) {\n return Promise.resolve();\n }\n\n if (!this.validateSettings()) {\n this.showSaveIndicator('Fix errors', 'text-danger');\n return Promise.resolve();\n }\n\n const settings = {};\n\n // Collect all form inputs with the \"ChatInteraction.\" prefix generically.\n // This avoids coupling the JS to specific field names — new fields added by\n // any module are automatically included.\n const inputs = this.getSettingInputs();\n\n inputs.forEach(input => {\n const key = input.dataset.setting\n || ((input.name || '').replace('ChatInteraction.', '').replace(/^[A-Z]/, match => match.toLowerCase()));\n\n if (!key) {\n return;\n }\n\n if (input.type === 'checkbox') {\n settings[key] = input.checked;\n } else if (input.type === 'number') {\n settings[key] = input.value ? parseFloat(input.value) : null;\n } else {\n settings[key] = input.value || null;\n }\n });\n\n // Add tool, MCP connection, and agent collections (special handling).\n settings.toolNames = this.getSelectedToolNames();\n settings.mcpConnectionIds = this.getSelectedMcpConnectionIds();\n settings.a2aConnectionIds = this.getSelectedA2AConnectionIds();\n settings.agentNames = this.getSelectedAgentNames();\n\n const promptTemplates = this.getPromptTemplateSelections();\n if (promptTemplates.length > 0) {\n settings.promptTemplates = promptTemplates;\n settings.promptTemplateIds = promptTemplates.map(template => template.templateId);\n }\n\n return this.connection.invoke(\"SaveSettings\", itemId, settings)\n .catch(err => {\n console.error('Error saving settings:', err);\n this.showSaveIndicator('Save failed', 'text-danger');\n });\n },\n flushPendingSave() {\n if (this.saveSettingsTimeout) {\n clearTimeout(this.saveSettingsTimeout);\n this.saveSettingsTimeout = null;\n }\n\n if (this.settingsDirty) {\n this.settingsDirty = false;\n return this.saveSettings();\n }\n\n return Promise.resolve();\n },\n initializeInteraction(itemId, force) {\n if (this.isInteractionStarted && !force) {\n return;\n }\n this.fireEvent(new CustomEvent(\"initializingChatInteraction\", { detail: { itemId: itemId } }));\n this.setItemId(itemId);\n this.isInteractionStarted = true;\n },\n copyResponse(message) {\n const text = message && typeof message === 'object'\n ? message.copyContent ?? message.content ?? ''\n : message ?? '';\n\n navigator.clipboard.writeText(text);\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var itemId = this.getItemId();\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", itemId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n }\n },\n watch: {\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n\n this.$nextTick(() => {\n refreshFontAwesomeIcons(this.$el);\n this.fontAwesomeObserver = observeFontAwesomeIcons(this.$el);\n });\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n if (this.fontAwesomeObserver) {\n this.fontAwesomeObserver.disconnect();\n this.fontAwesomeObserver = null;\n }\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n },\n template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\nwindow.chatInteractionDocumentManager = function () {\n const managerStateKey = '__chatInteractionDocumentManagerState';\n\n function normalizeDocumentInfo(document) {\n if (!document || typeof document !== 'object') {\n return null;\n }\n\n return {\n documentId: document.documentId || document.DocumentId || '',\n fileName: document.fileName || document.FileName || '',\n fileSize: document.fileSize || document.FileSize || 0\n };\n }\n\n function formatFileSize(bytes) {\n if (!bytes || bytes < 1024) {\n return (bytes || 0) + ' B';\n }\n\n if (bytes < 1024 * 1024) {\n return (bytes / 1024).toFixed(1) + ' KB';\n }\n\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n }\n\n function getDocumentKey(fileName, fileSize) {\n return ((fileName || '').trim().toLowerCase()) + '::' + (fileSize || 0);\n }\n\n function isDuplicateFile(file, knownKeys) {\n return knownKeys.has(getDocumentKey(file.name, file.size));\n }\n\n function getDocumentsFromDom(container) {\n if (!container) {\n return [];\n }\n\n return Array.from(container.querySelectorAll('[data-chat-document-id]'))\n .map(element => normalizeDocumentInfo({\n documentId: element.dataset.chatDocumentId,\n fileName: element.dataset.chatDocumentName,\n fileSize: Number(element.dataset.chatDocumentSize || 0)\n }))\n .filter(document => document && document.documentId);\n }\n\n function initialize(config) {\n if (!config || !config.itemId) {\n return;\n }\n\n const fileInput = document.getElementById('chat-doc-upload');\n const documentsList = document.getElementById('chat-documents-list');\n const status = document.getElementById('chat-doc-upload-status');\n const progressContainer = document.getElementById('chat-doc-upload-progress');\n const progressBar = document.getElementById('chat-doc-upload-progress-bar');\n const uploadQueue = document.getElementById('chat-doc-upload-queue');\n\n if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {\n return;\n }\n\n const previousState = fileInput[managerStateKey];\n if (previousState && typeof previousState.dispose === 'function') {\n previousState.dispose();\n }\n\n let interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n if (interactionDocuments.length === 0) {\n interactionDocuments = getDocumentsFromDom(documentsList);\n }\n\n let uploadItems = [];\n let isUploadingDocuments = false;\n\n function createTextElement(tagName, className, text) {\n const element = document.createElement(tagName);\n if (className) {\n element.className = className;\n }\n\n element.textContent = text;\n return element;\n }\n\n function renderDocuments() {\n documentsList.innerHTML = '';\n\n if (interactionDocuments.length === 0) {\n documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));\n return;\n }\n\n interactionDocuments.forEach(documentInfo => {\n const row = window.document.createElement('div');\n row.className = 'd-flex justify-content-between align-items-start gap-2 border rounded px-2 py-2 bg-white chat-document-row';\n row.dataset.chatDocumentId = documentInfo.documentId;\n row.dataset.chatDocumentName = documentInfo.fileName;\n row.dataset.chatDocumentSize = documentInfo.fileSize;\n\n const details = window.document.createElement('div');\n details.className = 'me-2 min-w-0';\n\n const name = createTextElement('div', 'fw-semibold small', documentInfo.fileName || 'Document');\n const icon = window.document.createElement('i');\n icon.className = 'bi bi-file-earmark-text me-1';\n name.prepend(icon);\n\n const size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));\n\n details.appendChild(name);\n details.appendChild(size);\n\n const removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', ' Remove');\n removeButton.type = 'button';\n removeButton.dataset.documentId = documentInfo.documentId;\n const removeIcon = window.document.createElement('i');\n removeIcon.className = 'bi bi-trash';\n removeButton.prepend(removeIcon);\n removeButton.addEventListener('click', () => removeDocument(documentInfo.documentId));\n\n row.appendChild(details);\n row.appendChild(removeButton);\n documentsList.appendChild(row);\n });\n }\n\n function showUploadStatus(message, cssClass) {\n if (!message) {\n status.textContent = '';\n status.className = 'small mt-2 d-none';\n return;\n }\n\n status.textContent = message;\n status.className = 'small mt-2 ' + (cssClass || 'text-muted');\n }\n\n function showUploadProgress(progress, message, cssClass) {\n if (progress === null || progress === undefined) {\n progressContainer.className = 'progress mt-2 d-none';\n progressContainer.setAttribute('aria-valuenow', '0');\n progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';\n progressBar.style.width = '0%';\n progressBar.textContent = '0%';\n return;\n }\n\n const roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));\n progressContainer.className = 'progress mt-2';\n progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());\n progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');\n progressBar.style.width = roundedProgress + '%';\n progressBar.textContent = message || (roundedProgress + '%');\n }\n\n function getUploadStatePresentation(state) {\n switch (state) {\n case 'uploaded':\n return { label: 'Uploaded', badgeClass: 'text-bg-success', progressClass: 'bg-success' };\n case 'failed':\n return { label: 'Failed', badgeClass: 'text-bg-danger', progressClass: 'bg-danger' };\n case 'uploading':\n return { label: 'Uploading', badgeClass: 'text-bg-warning', progressClass: 'bg-warning progress-bar-striped progress-bar-animated' };\n default:\n return { label: 'Queued', badgeClass: 'text-bg-secondary', progressClass: 'bg-secondary progress-bar-striped progress-bar-animated' };\n }\n }\n\n function formatUploadMessage(item) {\n if (item.status === 'failed' && item.error) {\n return item.error;\n }\n\n if (item.status === 'uploaded') {\n return 'Upload completed successfully.';\n }\n\n if (item.status === 'uploading') {\n return item.progress + '% uploaded';\n }\n\n return 'Waiting to upload...';\n }\n\n function renderUploadQueue() {\n uploadQueue.innerHTML = '';\n\n uploadItems.forEach(item => {\n const presentation = getUploadStatePresentation(item.status);\n const card = document.createElement('div');\n card.className = 'border rounded px-2 py-2 bg-white';\n\n const header = document.createElement('div');\n header.className = 'd-flex justify-content-between align-items-start gap-2';\n\n const fileDetails = document.createElement('div');\n fileDetails.className = 'flex-grow-1 min-w-0';\n fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));\n fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));\n\n const badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);\n\n header.appendChild(fileDetails);\n header.appendChild(badge);\n\n const progress = document.createElement('div');\n progress.className = 'progress mt-2';\n progress.setAttribute('role', 'progressbar');\n progress.setAttribute('aria-valuemin', '0');\n progress.setAttribute('aria-valuemax', '100');\n progress.setAttribute('aria-valuenow', item.progress.toString());\n\n const progressState = document.createElement('div');\n progressState.className = 'progress-bar ' + presentation.progressClass;\n progressState.style.width = item.progress + '%';\n progressState.textContent = item.progress + '%';\n progress.appendChild(progressState);\n\n const message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));\n\n card.appendChild(header);\n card.appendChild(progress);\n card.appendChild(message);\n uploadQueue.appendChild(card);\n });\n }\n\n function createUploadItem(file, index) {\n return {\n id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),\n fileName: file.name,\n fileSize: file.size,\n status: 'queued',\n progress: 0,\n error: null\n };\n }\n\n function updateUploadItem(itemId, updates) {\n uploadItems = uploadItems.map(item => item.id === itemId ? Object.assign({}, item, updates) : item);\n renderUploadQueue();\n }\n\n function removeUploadItems(predicate) {\n uploadItems = uploadItems.filter(item => !predicate(item));\n renderUploadQueue();\n }\n\n function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('chatInteractionId', config.itemId);\n formData.append('files', file);\n\n const xhr = new XMLHttpRequest();\n xhr.open('POST', config.uploadDocumentUrl, true);\n\n xhr.upload.addEventListener('progress', event => {\n if (!event.lengthComputable) {\n return;\n }\n\n const fileProgress = Math.round((event.loaded / event.total) * 100);\n updateUploadItem(itemIdToUpdate, {\n status: 'uploading',\n progress: fileProgress\n });\n\n const overallProgress = ((fileIndex + (event.loaded / event.total)) / totalFiles) * 100;\n showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (error) {\n reject(new Error('Upload failed: invalid server response.'));\n }\n\n return;\n }\n\n reject(new Error((xhr.responseText || 'Upload failed.').trim()));\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Upload failed. Please check your connection and try again.'));\n });\n\n xhr.send(formData);\n });\n }\n\n async function uploadDocuments(files) {\n if (!config.uploadDocumentUrl || !files || files.length === 0) {\n return;\n }\n\n if (isUploadingDocuments) {\n showUploadStatus('A document upload is already in progress.', 'text-warning');\n return;\n }\n\n isUploadingDocuments = true;\n\n const filesToUpload = [];\n const duplicateItems = [];\n const knownDocumentKeys = new Set(interactionDocuments.map(document => getDocumentKey(document.fileName, document.fileSize)));\n\n Array.from(files).forEach(file => {\n if (isDuplicateFile(file, knownDocumentKeys)) {\n duplicateItems.push(file);\n return;\n }\n\n knownDocumentKeys.add(getDocumentKey(file.name, file.size));\n filesToUpload.push(file);\n });\n\n if (duplicateItems.length > 0) {\n uploadItems = uploadItems.concat(duplicateItems.map((file, index) => Object.assign(createUploadItem(file, index), {\n status: 'failed',\n progress: 100,\n error: 'This document is already attached.'\n })));\n renderUploadQueue();\n }\n\n if (filesToUpload.length === 0) {\n isUploadingDocuments = false;\n showUploadStatus(duplicateItems.map(file => file.name + ': This document is already attached.').join(' | '), 'text-warning');\n showUploadProgress(null);\n return;\n }\n\n const pendingItems = filesToUpload.map(createUploadItem);\n uploadItems = uploadItems.concat(pendingItems);\n renderUploadQueue();\n showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');\n fileInput.disabled = true;\n\n try {\n let uploadedCount = 0;\n const failedUploads = duplicateItems.map(file => file.name + ': This document is already attached.');\n\n for (let i = 0; i < filesToUpload.length; i++) {\n const file = filesToUpload[i];\n const pendingItem = pendingItems[i];\n\n updateUploadItem(pendingItem.id, {\n status: 'uploading',\n progress: 0,\n error: null\n });\n\n showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');\n\n try {\n const result = await uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);\n const uploaded = (Array.isArray(result.uploaded) ? result.uploaded : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n const failed = Array.isArray(result.failed) ? result.failed : [];\n\n if (uploaded.length > 0) {\n uploadedCount += uploaded.length;\n interactionDocuments = interactionDocuments.concat(uploaded);\n updateUploadItem(pendingItem.id, {\n status: 'uploaded',\n progress: 100,\n error: null\n });\n } else {\n const missingUploadMessage = failed.length > 0\n ? failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ')\n : 'The server did not confirm that the file was uploaded.';\n if (failed.length === 0) {\n failedUploads.push(missingUploadMessage);\n }\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: missingUploadMessage\n });\n }\n\n if (failed.length > 0) {\n const failedMessage = failed.map(entry => entry.fileName + ': ' + entry.error).join(' | ');\n failedUploads.push(failedMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: 100,\n error: failedMessage\n });\n }\n } catch (error) {\n const errorMessage = error && error.message\n ? error.message\n : 'Upload failed. Please try again.';\n console.error('Upload failed:', error);\n failedUploads.push(file.name + ': ' + errorMessage);\n updateUploadItem(pendingItem.id, {\n status: 'failed',\n progress: pendingItem.progress || 0,\n error: errorMessage\n });\n }\n }\n\n renderDocuments();\n\n if (failedUploads.length > 0) {\n removeUploadItems(item => item.status === 'uploaded');\n showUploadStatus(\n (uploadedCount > 0 ? ('Uploaded ' + uploadedCount + ' document(s). ') : '') + failedUploads.join(' | '),\n uploadedCount > 0 ? 'text-warning' : 'text-danger');\n showUploadProgress(null);\n return;\n }\n\n removeUploadItems(() => true);\n showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');\n showUploadProgress(null);\n } catch (error) {\n console.error('Upload failed:', error);\n showUploadStatus('Upload failed. Please try again.', 'text-danger');\n showUploadProgress(null);\n } finally {\n isUploadingDocuments = false;\n fileInput.disabled = false;\n fileInput.value = '';\n }\n }\n\n async function removeDocument(documentId) {\n if (!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?')) {\n return;\n }\n\n try {\n const response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n itemId: config.itemId,\n documentId: documentId\n })\n });\n\n if (!response.ok) {\n console.error('Failed to remove document:', await response.text());\n showUploadStatus('Failed to remove document.', 'text-danger');\n return;\n }\n\n const result = await response.json();\n const serverDocuments = (Array.isArray(result.documents) ? result.documents : [])\n .map(normalizeDocumentInfo)\n .filter(document => document && document.documentId);\n\n interactionDocuments = serverDocuments.length > 0\n ? serverDocuments\n : interactionDocuments.filter(document => document.documentId !== documentId);\n renderDocuments();\n showUploadStatus('Document removed.', 'text-success');\n } catch (error) {\n console.error('Remove failed:', error);\n showUploadStatus('Failed to remove document.', 'text-danger');\n }\n }\n\n const onFileInputChange = event => {\n const selectedFiles = event.target.files ? Array.from(event.target.files) : [];\n uploadDocuments(selectedFiles);\n };\n\n fileInput.addEventListener('change', onFileInputChange);\n fileInput[managerStateKey] = {\n dispose: () => {\n fileInput.removeEventListener('change', onFileInputChange);\n }\n };\n\n renderDocuments();\n renderUploadQueue();\n showUploadStatus(null);\n showUploadProgress(null);\n }\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]}