@crestapps/ai-chat-ui 1.0.0-preview-22.6 → 1.0.0-preview.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-chat.css +362 -0
- package/dist/ai-chat.css.map +1 -0
- package/dist/ai-chat.js +685 -242
- package/dist/ai-chat.js.map +1 -1
- package/dist/ai-chat.min.css +1 -0
- package/dist/ai-chat.min.js +1 -1
- package/dist/ai-chat.min.js.map +1 -1
- package/dist/chat-interaction.js +33 -5
- package/dist/chat-interaction.js.map +1 -1
- package/dist/chat-interaction.min.js +1 -1
- package/dist/chat-interaction.min.js.map +1 -1
- package/dist/chat-widget.css +163 -9
- package/dist/chat-widget.css.map +1 -1
- package/dist/chat-widget.min.css +1 -1
- package/dist/document-drop-zone.js.map +1 -1
- package/dist/technical-name-generator.js.map +1 -1
- package/package.json +4 -1
package/dist/ai-chat.js
CHANGED
|
@@ -34,7 +34,25 @@ window.openAIChatManager = function () {
|
|
|
34
34
|
thumbsDownTitle: 'Thumbs down',
|
|
35
35
|
copyTitle: 'Click here to copy response to clipboard.',
|
|
36
36
|
codeCopiedText: 'Copied!',
|
|
37
|
-
|
|
37
|
+
widget: {
|
|
38
|
+
chatWidgetContainer: null,
|
|
39
|
+
chatWidgetStateName: null,
|
|
40
|
+
chatHistorySection: null,
|
|
41
|
+
showHistoryButton: null,
|
|
42
|
+
closeHistoryButton: null,
|
|
43
|
+
newChatButton: null,
|
|
44
|
+
toggleButtonSelector: null,
|
|
45
|
+
resetSizeButtonSelector: null,
|
|
46
|
+
dragHandleSelector: '.ai-chat-widget-header',
|
|
47
|
+
enableDragging: true,
|
|
48
|
+
enableResizing: true,
|
|
49
|
+
persistLayout: true,
|
|
50
|
+
defaultWidth: null,
|
|
51
|
+
defaultHeight: null,
|
|
52
|
+
minWidth: 320,
|
|
53
|
+
minHeight: 420
|
|
54
|
+
},
|
|
55
|
+
messageTemplate: "\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <i class=\"fa-regular fa-thumbs-up\"></i>\n </button>\n <button class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <i class=\"fa-regular fa-thumbs-down\"></i>\n </button>\n </span>\n </template>\n <button v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <i :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></i>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message.content)\" :title=\"copyTitle\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <i v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></i>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <i v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></i>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n ",
|
|
38
56
|
indicatorTemplate: "\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><i class=\"fa fa-robot\" style=\"display: inline-block;\"></i></span>\n Assistant\n </div>\n "
|
|
39
57
|
};
|
|
40
58
|
|
|
@@ -54,6 +72,19 @@ window.openAIChatManager = function () {
|
|
|
54
72
|
span.textContent = text;
|
|
55
73
|
return span.innerHTML;
|
|
56
74
|
}
|
|
75
|
+
function parsePixelValue(value) {
|
|
76
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
if (typeof value !== 'string') {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
var parsed = parseFloat(value);
|
|
83
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
84
|
+
}
|
|
85
|
+
function clamp(value, min, max) {
|
|
86
|
+
return Math.min(Math.max(value, min), max);
|
|
87
|
+
}
|
|
57
88
|
function normalizeReference(reference) {
|
|
58
89
|
var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$link;
|
|
59
90
|
if (!reference || _typeof(reference) !== 'object') {
|
|
@@ -330,6 +361,8 @@ window.openAIChatManager = function () {
|
|
|
330
361
|
}
|
|
331
362
|
var initialize = function initialize(instanceConfig) {
|
|
332
363
|
var config = Object.assign({}, defaultConfig, instanceConfig);
|
|
364
|
+
config.widget = Object.assign({}, defaultConfig.widget || {}, instanceConfig && instanceConfig.widget ? instanceConfig.widget : {});
|
|
365
|
+
var hasWidgetConfig = !!(instanceConfig && instanceConfig.widget && instanceConfig.widget.chatWidgetContainer && instanceConfig.widget.chatWidgetStateName);
|
|
333
366
|
// Keep defaultConfig in sync so renderers use overridden values
|
|
334
367
|
defaultConfig = config;
|
|
335
368
|
if (!config.signalRHubUrl) {
|
|
@@ -363,7 +396,15 @@ window.openAIChatManager = function () {
|
|
|
363
396
|
isPlaceholderVisible: true,
|
|
364
397
|
chatWidgetStateName: null,
|
|
365
398
|
chatWidgetStateSession: null,
|
|
399
|
+
chatWidgetLayoutKey: null,
|
|
366
400
|
chatHistorySection: null,
|
|
401
|
+
widgetContainerElement: null,
|
|
402
|
+
widgetToggleButtonElement: null,
|
|
403
|
+
widgetResetSizeButtonElement: null,
|
|
404
|
+
widgetResizeObserver: null,
|
|
405
|
+
widgetViewportResizeHandler: null,
|
|
406
|
+
widgetDefaultWidth: null,
|
|
407
|
+
widgetDefaultHeight: null,
|
|
367
408
|
widgetIsInitialized: false,
|
|
368
409
|
isStreaming: false,
|
|
369
410
|
isNavigatingAway: false,
|
|
@@ -394,9 +435,11 @@ window.openAIChatManager = function () {
|
|
|
394
435
|
audioPlayQueue: [],
|
|
395
436
|
isPlayingAudio: false,
|
|
396
437
|
currentAudioElement: null,
|
|
438
|
+
currentAudioUrl: null,
|
|
397
439
|
ttsButton: null,
|
|
398
440
|
ttsPlayingMessageIndex: -1,
|
|
399
441
|
ttsAudioCache: {},
|
|
442
|
+
ttsInstanceId: 'ai-chat-' + Math.random().toString(36).slice(2),
|
|
400
443
|
singleResponseMode: !!config.singleResponseMode,
|
|
401
444
|
conversationModeEnabled: config.chatMode === 'Conversation',
|
|
402
445
|
conversationButton: null,
|
|
@@ -418,6 +461,336 @@ window.openAIChatManager = function () {
|
|
|
418
461
|
handleBeforeUnload: function handleBeforeUnload() {
|
|
419
462
|
this.isNavigatingAway = true;
|
|
420
463
|
},
|
|
464
|
+
getStoredWidgetLayout: function getStoredWidgetLayout() {
|
|
465
|
+
if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {
|
|
466
|
+
return {};
|
|
467
|
+
}
|
|
468
|
+
try {
|
|
469
|
+
var storedLayout = localStorage.getItem(this.chatWidgetLayoutKey);
|
|
470
|
+
return storedLayout ? JSON.parse(storedLayout) || {} : {};
|
|
471
|
+
} catch (error) {
|
|
472
|
+
console.warn('Failed to read widget layout state.', error);
|
|
473
|
+
return {};
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
saveStoredWidgetLayout: function saveStoredWidgetLayout(partialLayout) {
|
|
477
|
+
if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
var currentLayout = this.getStoredWidgetLayout();
|
|
481
|
+
var nextLayout = Object.assign({}, currentLayout);
|
|
482
|
+
if (partialLayout.panel !== undefined) {
|
|
483
|
+
nextLayout.panel = Object.assign({}, currentLayout.panel || {}, partialLayout.panel || {});
|
|
484
|
+
}
|
|
485
|
+
if (partialLayout.position !== undefined) {
|
|
486
|
+
nextLayout.position = Object.assign({}, currentLayout.position || {}, partialLayout.position || {});
|
|
487
|
+
}
|
|
488
|
+
localStorage.setItem(this.chatWidgetLayoutKey, JSON.stringify(nextLayout));
|
|
489
|
+
},
|
|
490
|
+
getElementSize: function getElementSize(element, fallbackWidth, fallbackHeight) {
|
|
491
|
+
if (!element) {
|
|
492
|
+
return {
|
|
493
|
+
width: fallbackWidth || 0,
|
|
494
|
+
height: fallbackHeight || 0
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
var rect = element.getBoundingClientRect();
|
|
498
|
+
var computed = window.getComputedStyle(element);
|
|
499
|
+
return {
|
|
500
|
+
width: Math.round(rect.width || parsePixelValue(computed.width) || fallbackWidth || 0),
|
|
501
|
+
height: Math.round(rect.height || parsePixelValue(computed.height) || fallbackHeight || 0)
|
|
502
|
+
};
|
|
503
|
+
},
|
|
504
|
+
getElementPosition: function getElementPosition(element) {
|
|
505
|
+
if (!element) {
|
|
506
|
+
return {
|
|
507
|
+
left: 0,
|
|
508
|
+
top: 0
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
var rect = element.getBoundingClientRect();
|
|
512
|
+
var computed = window.getComputedStyle(element);
|
|
513
|
+
var inlineLeft = parsePixelValue(element.style.left);
|
|
514
|
+
var inlineTop = parsePixelValue(element.style.top);
|
|
515
|
+
var computedLeft = parsePixelValue(computed.left);
|
|
516
|
+
var computedTop = parsePixelValue(computed.top);
|
|
517
|
+
var isHidden = computed.display === 'none';
|
|
518
|
+
return {
|
|
519
|
+
left: Math.round(isHidden && Number.isFinite(inlineLeft) ? inlineLeft : rect.left || inlineLeft || computedLeft || 0),
|
|
520
|
+
top: Math.round(isHidden && Number.isFinite(inlineTop) ? inlineTop : rect.top || inlineTop || computedTop || 0)
|
|
521
|
+
};
|
|
522
|
+
},
|
|
523
|
+
clampWidgetPosition: function clampWidgetPosition(left, top, width, height) {
|
|
524
|
+
var viewportPadding = 8;
|
|
525
|
+
var maxLeft = Math.max(viewportPadding, window.innerWidth - width - viewportPadding);
|
|
526
|
+
var maxTop = Math.max(viewportPadding, window.innerHeight - height - viewportPadding);
|
|
527
|
+
return {
|
|
528
|
+
left: Math.round(clamp(left, viewportPadding, maxLeft)),
|
|
529
|
+
top: Math.round(clamp(top, viewportPadding, maxTop))
|
|
530
|
+
};
|
|
531
|
+
},
|
|
532
|
+
applyAbsolutePosition: function applyAbsolutePosition(element, left, top) {
|
|
533
|
+
if (!element) {
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
element.style.left = left + 'px';
|
|
537
|
+
element.style.top = top + 'px';
|
|
538
|
+
element.style.right = 'auto';
|
|
539
|
+
element.style.bottom = 'auto';
|
|
540
|
+
},
|
|
541
|
+
getWidgetDefaultSize: function getWidgetDefaultSize() {
|
|
542
|
+
return {
|
|
543
|
+
width: this.widgetDefaultWidth || parsePixelValue(config.widget.defaultWidth) || 380,
|
|
544
|
+
height: this.widgetDefaultHeight || parsePixelValue(config.widget.defaultHeight) || 520
|
|
545
|
+
};
|
|
546
|
+
},
|
|
547
|
+
getWidgetToggleGap: function getWidgetToggleGap() {
|
|
548
|
+
return 8;
|
|
549
|
+
},
|
|
550
|
+
isWidgetPanelVisible: function isWidgetPanelVisible() {
|
|
551
|
+
if (!this.widgetContainerElement) {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
var computed = window.getComputedStyle(this.widgetContainerElement);
|
|
555
|
+
return this.widgetContainerElement.classList.contains('open') && computed.display !== 'none';
|
|
556
|
+
},
|
|
557
|
+
persistWidgetPanelPosition: function persistWidgetPanelPosition() {
|
|
558
|
+
if (!this.widgetContainerElement || !config.widget.persistLayout) {
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
var panelDefaultSize = this.getWidgetDefaultSize();
|
|
562
|
+
var panelPosition = this.getElementPosition(this.widgetContainerElement);
|
|
563
|
+
var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);
|
|
564
|
+
var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);
|
|
565
|
+
var linkedPosition = this.clampWidgetPosition(panelPosition.left + panelSize.width - toggleSize.width, panelPosition.top + panelSize.height + this.getWidgetToggleGap(), toggleSize.width, toggleSize.height);
|
|
566
|
+
this.saveStoredWidgetLayout({
|
|
567
|
+
position: {
|
|
568
|
+
left: linkedPosition.left,
|
|
569
|
+
top: linkedPosition.top
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
},
|
|
573
|
+
persistWidgetTogglePosition: function persistWidgetTogglePosition() {
|
|
574
|
+
if (!this.widgetToggleButtonElement || !config.widget.persistLayout) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect();
|
|
578
|
+
this.saveStoredWidgetLayout({
|
|
579
|
+
position: {
|
|
580
|
+
left: this.getElementPosition(this.widgetToggleButtonElement).left,
|
|
581
|
+
top: this.getElementPosition(this.widgetToggleButtonElement).top
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
},
|
|
585
|
+
persistWidgetPanelSize: function persistWidgetPanelSize() {
|
|
586
|
+
if (!this.widgetContainerElement || !config.widget.enableResizing || !config.widget.persistLayout) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
var defaultSize = this.getWidgetDefaultSize();
|
|
590
|
+
var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);
|
|
591
|
+
this.saveStoredWidgetLayout({
|
|
592
|
+
panel: {
|
|
593
|
+
width: Math.abs(currentSize.width - defaultSize.width) <= 1 ? null : currentSize.width,
|
|
594
|
+
height: Math.abs(currentSize.height - defaultSize.height) <= 1 ? null : currentSize.height
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
},
|
|
598
|
+
syncTogglePositionToPanel: function syncTogglePositionToPanel() {
|
|
599
|
+
var persistLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
600
|
+
if (!this.widgetContainerElement || !this.widgetToggleButtonElement) {
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
var panelDefaultSize = this.getWidgetDefaultSize();
|
|
604
|
+
var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);
|
|
605
|
+
var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);
|
|
606
|
+
var panelPosition = this.getElementPosition(this.widgetContainerElement);
|
|
607
|
+
var linkedPosition = this.clampWidgetPosition(panelPosition.left + panelSize.width - toggleSize.width, panelPosition.top + panelSize.height + this.getWidgetToggleGap(), toggleSize.width, toggleSize.height);
|
|
608
|
+
this.applyAbsolutePosition(this.widgetToggleButtonElement, linkedPosition.left, linkedPosition.top);
|
|
609
|
+
if (persistLayout && config.widget.persistLayout) {
|
|
610
|
+
this.persistWidgetTogglePosition();
|
|
611
|
+
}
|
|
612
|
+
},
|
|
613
|
+
syncPanelPositionToToggle: function syncPanelPositionToToggle() {
|
|
614
|
+
var persistLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
615
|
+
if (!this.widgetContainerElement || !this.widgetToggleButtonElement) {
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
var panelDefaultSize = this.getWidgetDefaultSize();
|
|
619
|
+
var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);
|
|
620
|
+
var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);
|
|
621
|
+
var togglePosition = this.getElementPosition(this.widgetToggleButtonElement);
|
|
622
|
+
var linkedPosition = this.clampWidgetPosition(togglePosition.left + toggleSize.width - panelSize.width, togglePosition.top - panelSize.height - this.getWidgetToggleGap(), panelSize.width, panelSize.height);
|
|
623
|
+
this.applyAbsolutePosition(this.widgetContainerElement, linkedPosition.left, linkedPosition.top);
|
|
624
|
+
if (persistLayout && config.widget.persistLayout) {
|
|
625
|
+
this.persistWidgetPanelPosition();
|
|
626
|
+
}
|
|
627
|
+
},
|
|
628
|
+
updateWidgetResetSizeButtonVisibility: function updateWidgetResetSizeButtonVisibility() {
|
|
629
|
+
if (!this.widgetResetSizeButtonElement) {
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
if (!config.widget.enableResizing || !this.widgetContainerElement) {
|
|
633
|
+
this.widgetResetSizeButtonElement.classList.add('d-none');
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
var defaultSize = this.getWidgetDefaultSize();
|
|
637
|
+
var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);
|
|
638
|
+
var isResized = Math.abs(currentSize.width - defaultSize.width) > 1 || Math.abs(currentSize.height - defaultSize.height) > 1 || !!this.widgetContainerElement.style.width || !!this.widgetContainerElement.style.height;
|
|
639
|
+
this.widgetResetSizeButtonElement.classList.toggle('d-none', !isResized);
|
|
640
|
+
},
|
|
641
|
+
resetWidgetSize: function resetWidgetSize() {
|
|
642
|
+
if (!this.widgetContainerElement || !config.widget.enableResizing) {
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
this.widgetContainerElement.style.removeProperty('width');
|
|
646
|
+
this.widgetContainerElement.style.removeProperty('height');
|
|
647
|
+
this.persistWidgetPanelSize();
|
|
648
|
+
this.constrainWidgetElementsToViewport();
|
|
649
|
+
this.updateWidgetResetSizeButtonVisibility();
|
|
650
|
+
},
|
|
651
|
+
restoreWidgetLayout: function restoreWidgetLayout() {
|
|
652
|
+
var storedLayout = this.getStoredWidgetLayout();
|
|
653
|
+
if (this.widgetContainerElement && config.widget.enableResizing) {
|
|
654
|
+
if (Number.isFinite(storedLayout.panel && storedLayout.panel.width)) {
|
|
655
|
+
this.widgetContainerElement.style.width = storedLayout.panel.width + 'px';
|
|
656
|
+
} else {
|
|
657
|
+
this.widgetContainerElement.style.removeProperty('width');
|
|
658
|
+
}
|
|
659
|
+
if (Number.isFinite(storedLayout.panel && storedLayout.panel.height)) {
|
|
660
|
+
this.widgetContainerElement.style.height = storedLayout.panel.height + 'px';
|
|
661
|
+
} else {
|
|
662
|
+
this.widgetContainerElement.style.removeProperty('height');
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
if (this.widgetToggleButtonElement && config.widget.enableDragging && Number.isFinite(storedLayout.position && storedLayout.position.left) && Number.isFinite(storedLayout.position && storedLayout.position.top)) {
|
|
666
|
+
this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.position.left, storedLayout.position.top);
|
|
667
|
+
this.syncPanelPositionToToggle(false);
|
|
668
|
+
} else if (this.widgetToggleButtonElement && config.widget.enableDragging && Number.isFinite(storedLayout.toggle && storedLayout.toggle.left) && Number.isFinite(storedLayout.toggle && storedLayout.toggle.top)) {
|
|
669
|
+
this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.toggle.left, storedLayout.toggle.top);
|
|
670
|
+
this.syncPanelPositionToToggle(false);
|
|
671
|
+
} else if (this.widgetContainerElement && config.widget.enableDragging && Number.isFinite(storedLayout.panel && storedLayout.panel.left) && Number.isFinite(storedLayout.panel && storedLayout.panel.top)) {
|
|
672
|
+
this.applyAbsolutePosition(this.widgetContainerElement, storedLayout.panel.left, storedLayout.panel.top);
|
|
673
|
+
this.syncTogglePositionToPanel(false);
|
|
674
|
+
}
|
|
675
|
+
this.constrainWidgetElementsToViewport();
|
|
676
|
+
this.updateWidgetResetSizeButtonVisibility();
|
|
677
|
+
},
|
|
678
|
+
attachDraggableWidgetElement: function attachDraggableWidgetElement(element, handle, layoutKey, suppressClickOnDrag) {
|
|
679
|
+
var _this = this;
|
|
680
|
+
if (!element || !handle || !config.widget.enableDragging) {
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
var activePointerId = null;
|
|
684
|
+
var startX = 0;
|
|
685
|
+
var startY = 0;
|
|
686
|
+
var startLeft = 0;
|
|
687
|
+
var startTop = 0;
|
|
688
|
+
var dragged = false;
|
|
689
|
+
var dragThreshold = 4;
|
|
690
|
+
var interactiveSelector = 'button, a, input, textarea, select, option, label';
|
|
691
|
+
var _stopDragging = function stopDragging(event) {
|
|
692
|
+
if (activePointerId === null) {
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
if (event && event.pointerId !== undefined && event.pointerId !== activePointerId) {
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
document.removeEventListener('pointermove', onPointerMove);
|
|
699
|
+
document.removeEventListener('pointerup', _stopDragging);
|
|
700
|
+
document.removeEventListener('pointercancel', _stopDragging);
|
|
701
|
+
element.classList.remove('ai-chat-widget-dragging');
|
|
702
|
+
activePointerId = null;
|
|
703
|
+
if (!dragged) {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
if (layoutKey === 'panel') {
|
|
707
|
+
_this.syncTogglePositionToPanel(false);
|
|
708
|
+
_this.persistWidgetPanelPosition();
|
|
709
|
+
} else if (layoutKey === 'toggle') {
|
|
710
|
+
_this.syncPanelPositionToToggle(false);
|
|
711
|
+
_this.persistWidgetTogglePosition();
|
|
712
|
+
}
|
|
713
|
+
if (config.widget.persistLayout) {
|
|
714
|
+
_this.persistWidgetPanelPosition();
|
|
715
|
+
_this.persistWidgetTogglePosition();
|
|
716
|
+
}
|
|
717
|
+
if (suppressClickOnDrag) {
|
|
718
|
+
element.dataset.dragSuppressClick = 'true';
|
|
719
|
+
window.setTimeout(function () {
|
|
720
|
+
if (element.dataset.dragSuppressClick === 'true') {
|
|
721
|
+
element.dataset.dragSuppressClick = 'false';
|
|
722
|
+
}
|
|
723
|
+
}, 0);
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
var onPointerMove = function onPointerMove(event) {
|
|
727
|
+
if (activePointerId === null || event.pointerId !== activePointerId) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
var deltaX = event.clientX - startX;
|
|
731
|
+
var deltaY = event.clientY - startY;
|
|
732
|
+
if (!dragged && Math.hypot(deltaX, deltaY) < dragThreshold) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
dragged = true;
|
|
736
|
+
var defaultSize = _this.getWidgetDefaultSize();
|
|
737
|
+
var currentSize = _this.getElementSize(element, layoutKey === 'panel' ? defaultSize.width : 52, layoutKey === 'panel' ? defaultSize.height : 52);
|
|
738
|
+
var nextPosition = _this.clampWidgetPosition(startLeft + deltaX, startTop + deltaY, currentSize.width, currentSize.height);
|
|
739
|
+
_this.applyAbsolutePosition(element, nextPosition.left, nextPosition.top);
|
|
740
|
+
if (layoutKey === 'panel') {
|
|
741
|
+
_this.syncTogglePositionToPanel(false);
|
|
742
|
+
} else if (layoutKey === 'toggle') {
|
|
743
|
+
_this.syncPanelPositionToToggle(false);
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
handle.addEventListener('pointerdown', function (event) {
|
|
747
|
+
if (event.button !== 0) {
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
if (layoutKey === 'panel' && event.target.closest(interactiveSelector)) {
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
var rect = element.getBoundingClientRect();
|
|
754
|
+
startX = event.clientX;
|
|
755
|
+
startY = event.clientY;
|
|
756
|
+
startLeft = rect.left;
|
|
757
|
+
startTop = rect.top;
|
|
758
|
+
dragged = false;
|
|
759
|
+
activePointerId = event.pointerId;
|
|
760
|
+
element.classList.add('ai-chat-widget-dragging');
|
|
761
|
+
if (handle.setPointerCapture) {
|
|
762
|
+
handle.setPointerCapture(event.pointerId);
|
|
763
|
+
}
|
|
764
|
+
document.addEventListener('pointermove', onPointerMove);
|
|
765
|
+
document.addEventListener('pointerup', _stopDragging);
|
|
766
|
+
document.addEventListener('pointercancel', _stopDragging);
|
|
767
|
+
event.preventDefault();
|
|
768
|
+
});
|
|
769
|
+
},
|
|
770
|
+
constrainWidgetElementsToViewport: function constrainWidgetElementsToViewport() {
|
|
771
|
+
if (this.widgetContainerElement && this.widgetContainerElement.style.left && this.isWidgetPanelVisible()) {
|
|
772
|
+
var panelDefaultSize = this.getWidgetDefaultSize();
|
|
773
|
+
var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);
|
|
774
|
+
var panelPosition = this.getElementPosition(this.widgetContainerElement);
|
|
775
|
+
var clampedPanel = this.clampWidgetPosition(panelPosition.left, panelPosition.top, panelSize.width, panelSize.height);
|
|
776
|
+
this.applyAbsolutePosition(this.widgetContainerElement, clampedPanel.left, clampedPanel.top);
|
|
777
|
+
this.syncTogglePositionToPanel(false);
|
|
778
|
+
if (config.widget.persistLayout) {
|
|
779
|
+
this.persistWidgetPanelPosition();
|
|
780
|
+
this.persistWidgetTogglePosition();
|
|
781
|
+
}
|
|
782
|
+
} else if (this.widgetToggleButtonElement && this.widgetToggleButtonElement.style.left) {
|
|
783
|
+
var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);
|
|
784
|
+
var togglePosition = this.getElementPosition(this.widgetToggleButtonElement);
|
|
785
|
+
var clampedToggle = this.clampWidgetPosition(togglePosition.left, togglePosition.top, toggleSize.width, toggleSize.height);
|
|
786
|
+
this.applyAbsolutePosition(this.widgetToggleButtonElement, clampedToggle.left, clampedToggle.top);
|
|
787
|
+
this.syncPanelPositionToToggle(false);
|
|
788
|
+
if (config.widget.persistLayout) {
|
|
789
|
+
this.persistWidgetTogglePosition();
|
|
790
|
+
this.persistWidgetPanelPosition();
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
},
|
|
421
794
|
handleDragOver: function handleDragOver(e) {
|
|
422
795
|
if (!config.sessionDocumentsEnabled) return;
|
|
423
796
|
e.preventDefault();
|
|
@@ -458,7 +831,7 @@ window.openAIChatManager = function () {
|
|
|
458
831
|
e.target.value = '';
|
|
459
832
|
},
|
|
460
833
|
uploadFiles: function uploadFiles(files) {
|
|
461
|
-
var
|
|
834
|
+
var _this2 = this;
|
|
462
835
|
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
|
|
463
836
|
var sessionId, profileId, formData, i, response, errorText, uploadError, result, j, _t;
|
|
464
837
|
return _regenerator().w(function (_context) {
|
|
@@ -470,8 +843,8 @@ window.openAIChatManager = function () {
|
|
|
470
843
|
}
|
|
471
844
|
return _context.a(2);
|
|
472
845
|
case 1:
|
|
473
|
-
sessionId =
|
|
474
|
-
profileId =
|
|
846
|
+
sessionId = _this2.getSessionId();
|
|
847
|
+
profileId = _this2.getProfileId();
|
|
475
848
|
if (!(!sessionId && !profileId)) {
|
|
476
849
|
_context.n = 2;
|
|
477
850
|
break;
|
|
@@ -479,9 +852,9 @@ window.openAIChatManager = function () {
|
|
|
479
852
|
console.warn('Cannot upload documents without a session or profile.');
|
|
480
853
|
return _context.a(2);
|
|
481
854
|
case 2:
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
855
|
+
_this2.isUploading = true;
|
|
856
|
+
_this2.uploadErrors = [];
|
|
857
|
+
_this2.renderDocumentBar();
|
|
485
858
|
_context.p = 3;
|
|
486
859
|
formData = new FormData();
|
|
487
860
|
if (sessionId) {
|
|
@@ -507,9 +880,9 @@ window.openAIChatManager = function () {
|
|
|
507
880
|
return response.text();
|
|
508
881
|
case 5:
|
|
509
882
|
errorText = _context.v;
|
|
510
|
-
uploadError =
|
|
883
|
+
uploadError = _this2.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');
|
|
511
884
|
console.error('Upload failed:', errorText);
|
|
512
|
-
|
|
885
|
+
_this2.uploadErrors = [{
|
|
513
886
|
fileName: '',
|
|
514
887
|
error: uploadError
|
|
515
888
|
}];
|
|
@@ -521,15 +894,15 @@ window.openAIChatManager = function () {
|
|
|
521
894
|
result = _context.v;
|
|
522
895
|
// If the server created a new session, initialize it.
|
|
523
896
|
if (result.sessionId && !sessionId) {
|
|
524
|
-
|
|
897
|
+
_this2.initializeSession(result.sessionId);
|
|
525
898
|
}
|
|
526
899
|
if (result.uploaded && result.uploaded.length > 0) {
|
|
527
900
|
for (j = 0; j < result.uploaded.length; j++) {
|
|
528
|
-
|
|
901
|
+
_this2.documents.push(result.uploaded[j]);
|
|
529
902
|
}
|
|
530
903
|
}
|
|
531
904
|
if (result.failed && result.failed.length > 0) {
|
|
532
|
-
|
|
905
|
+
_this2.uploadErrors = result.failed;
|
|
533
906
|
}
|
|
534
907
|
_context.n = 9;
|
|
535
908
|
break;
|
|
@@ -537,14 +910,14 @@ window.openAIChatManager = function () {
|
|
|
537
910
|
_context.p = 8;
|
|
538
911
|
_t = _context.v;
|
|
539
912
|
console.error('Upload error:', _t);
|
|
540
|
-
|
|
913
|
+
_this2.uploadErrors = [{
|
|
541
914
|
fileName: '',
|
|
542
915
|
error: 'Upload failed. Please try again.'
|
|
543
916
|
}];
|
|
544
917
|
case 9:
|
|
545
918
|
_context.p = 9;
|
|
546
|
-
|
|
547
|
-
|
|
919
|
+
_this2.isUploading = false;
|
|
920
|
+
_this2.renderDocumentBar();
|
|
548
921
|
return _context.f(9);
|
|
549
922
|
case 10:
|
|
550
923
|
return _context.a(2);
|
|
@@ -553,7 +926,7 @@ window.openAIChatManager = function () {
|
|
|
553
926
|
}))();
|
|
554
927
|
},
|
|
555
928
|
removeDocument: function removeDocument(doc) {
|
|
556
|
-
var
|
|
929
|
+
var _this3 = this;
|
|
557
930
|
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
558
931
|
var sessionId, response, idx, errorText, removeError, _t2;
|
|
559
932
|
return _regenerator().w(function (_context2) {
|
|
@@ -566,7 +939,7 @@ window.openAIChatManager = function () {
|
|
|
566
939
|
return _context2.a(2);
|
|
567
940
|
case 1:
|
|
568
941
|
_context2.p = 1;
|
|
569
|
-
sessionId =
|
|
942
|
+
sessionId = _this3.getSessionId();
|
|
570
943
|
_context2.n = 2;
|
|
571
944
|
return fetch(config.removeDocumentUrl, {
|
|
572
945
|
method: 'POST',
|
|
@@ -584,8 +957,8 @@ window.openAIChatManager = function () {
|
|
|
584
957
|
_context2.n = 3;
|
|
585
958
|
break;
|
|
586
959
|
}
|
|
587
|
-
idx =
|
|
588
|
-
if (idx > -1)
|
|
960
|
+
idx = _this3.documents.indexOf(doc);
|
|
961
|
+
if (idx > -1) _this3.documents.splice(idx, 1);
|
|
589
962
|
_context2.n = 5;
|
|
590
963
|
break;
|
|
591
964
|
case 3:
|
|
@@ -593,13 +966,13 @@ window.openAIChatManager = function () {
|
|
|
593
966
|
return response.text();
|
|
594
967
|
case 4:
|
|
595
968
|
errorText = _context2.v;
|
|
596
|
-
removeError =
|
|
969
|
+
removeError = _this3.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');
|
|
597
970
|
console.error('Failed to remove document:', response.status, errorText);
|
|
598
|
-
|
|
971
|
+
_this3.uploadErrors = [{
|
|
599
972
|
fileName: doc.fileName || '',
|
|
600
973
|
error: removeError
|
|
601
974
|
}];
|
|
602
|
-
|
|
975
|
+
_this3.renderDocumentBar();
|
|
603
976
|
case 5:
|
|
604
977
|
_context2.n = 7;
|
|
605
978
|
break;
|
|
@@ -607,11 +980,11 @@ window.openAIChatManager = function () {
|
|
|
607
980
|
_context2.p = 6;
|
|
608
981
|
_t2 = _context2.v;
|
|
609
982
|
console.error('Remove document error:', _t2);
|
|
610
|
-
|
|
983
|
+
_this3.uploadErrors = [{
|
|
611
984
|
fileName: doc.fileName || '',
|
|
612
985
|
error: 'Failed to remove document. Please try again.'
|
|
613
986
|
}];
|
|
614
|
-
|
|
987
|
+
_this3.renderDocumentBar();
|
|
615
988
|
case 7:
|
|
616
989
|
return _context2.a(2);
|
|
617
990
|
}
|
|
@@ -781,139 +1154,139 @@ window.openAIChatManager = function () {
|
|
|
781
1154
|
return !!message && message.isStreaming && index === this.lastAssistantIndex && !(appearance && appearance.disableStreamingAnimation);
|
|
782
1155
|
},
|
|
783
1156
|
startConnection: function startConnection() {
|
|
784
|
-
var
|
|
1157
|
+
var _this4 = this;
|
|
785
1158
|
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
|
|
786
1159
|
var _t3;
|
|
787
1160
|
return _regenerator().w(function (_context3) {
|
|
788
1161
|
while (1) switch (_context3.p = _context3.n) {
|
|
789
1162
|
case 0:
|
|
790
|
-
|
|
1163
|
+
_this4.connection = new signalR.HubConnectionBuilder().withUrl(config.signalRHubUrl).withAutomaticReconnect().build();
|
|
791
1164
|
|
|
792
1165
|
// Allow long-running operations (e.g., multi-step MCP tool calls)
|
|
793
1166
|
// without the client disconnecting prematurely.
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
1167
|
+
_this4.connection.serverTimeoutInMilliseconds = 600000;
|
|
1168
|
+
_this4.connection.keepAliveIntervalInMilliseconds = 15000;
|
|
1169
|
+
_this4.connection.on("LoadSession", function (data) {
|
|
797
1170
|
var _data$messages;
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
1171
|
+
_this4.initializeSession(data.sessionId, true);
|
|
1172
|
+
_this4.messages = [];
|
|
1173
|
+
_this4.documents = data.documents || [];
|
|
801
1174
|
((_data$messages = data.messages) !== null && _data$messages !== void 0 ? _data$messages : []).forEach(function (msg) {
|
|
802
|
-
|
|
803
|
-
|
|
1175
|
+
_this4.addMessage(msg);
|
|
1176
|
+
_this4.$nextTick(function () {
|
|
804
1177
|
renderChartsInMessage(msg);
|
|
805
1178
|
});
|
|
806
1179
|
});
|
|
807
1180
|
|
|
808
1181
|
// Update feedback icons in the DOM after all messages have rendered.
|
|
809
|
-
|
|
810
|
-
|
|
1182
|
+
_this4.$nextTick(function () {
|
|
1183
|
+
_this4.refreshAllFeedbackIcons();
|
|
811
1184
|
});
|
|
812
1185
|
|
|
813
1186
|
// When the session is new (no messages) and an initial prompt is configured,
|
|
814
1187
|
// automatically send it as the first user message to trigger an AI response.
|
|
815
|
-
if (
|
|
816
|
-
|
|
817
|
-
|
|
1188
|
+
if (_this4.messages.length === 0 && config.initialPrompt) {
|
|
1189
|
+
_this4.prompt = config.initialPrompt;
|
|
1190
|
+
_this4.sendMessage();
|
|
818
1191
|
}
|
|
819
1192
|
});
|
|
820
|
-
|
|
1193
|
+
_this4.connection.on("ReceiveError", function (error) {
|
|
821
1194
|
console.error("SignalR Error: ", error);
|
|
822
|
-
if (
|
|
823
|
-
|
|
1195
|
+
if (_this4.isRecording) {
|
|
1196
|
+
_this4.stopRecording();
|
|
824
1197
|
}
|
|
825
1198
|
|
|
826
1199
|
// If this is a widget with a stale cached session (e.g., profile was deleted),
|
|
827
1200
|
// clear the cached session and start fresh with the current profile.
|
|
828
|
-
if (
|
|
829
|
-
|
|
830
|
-
localStorage.removeItem(
|
|
831
|
-
|
|
1201
|
+
if (_this4.widgetIsInitialized && !_this4.isSessionStarted && !_this4._attemptedSessionRecovery) {
|
|
1202
|
+
_this4._attemptedSessionRecovery = true;
|
|
1203
|
+
localStorage.removeItem(_this4.chatWidgetStateSession);
|
|
1204
|
+
_this4.startNewSession();
|
|
832
1205
|
}
|
|
833
1206
|
});
|
|
834
|
-
|
|
835
|
-
var msg =
|
|
1207
|
+
_this4.connection.on("MessageRated", function (messageId, userRating) {
|
|
1208
|
+
var msg = _this4.messages.find(function (m) {
|
|
836
1209
|
return m.id === messageId;
|
|
837
1210
|
});
|
|
838
1211
|
if (msg) {
|
|
839
1212
|
msg.userRating = userRating;
|
|
840
1213
|
}
|
|
841
1214
|
});
|
|
842
|
-
|
|
843
|
-
if (
|
|
1215
|
+
_this4.connection.on("ReceiveTranscript", function (sessionId, text, isFinal) {
|
|
1216
|
+
if (_this4.isConversationMode) {
|
|
844
1217
|
if (!isFinal && text) {
|
|
845
|
-
|
|
1218
|
+
_this4._conversationPartialTranscript = text;
|
|
846
1219
|
var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
847
1220
|
var html = '<p class="ai-partial-transcript">' + escaped + '</p>';
|
|
848
1221
|
|
|
849
1222
|
// Show partial transcript as a live user message.
|
|
850
|
-
if (!
|
|
851
|
-
|
|
852
|
-
|
|
1223
|
+
if (!_this4._conversationPartialMessage) {
|
|
1224
|
+
_this4.hidePlaceholder();
|
|
1225
|
+
_this4._conversationPartialMessage = {
|
|
853
1226
|
role: 'user',
|
|
854
1227
|
content: text,
|
|
855
1228
|
htmlContent: html,
|
|
856
1229
|
isPartial: true
|
|
857
1230
|
};
|
|
858
|
-
|
|
1231
|
+
_this4.messages.push(_this4._conversationPartialMessage);
|
|
859
1232
|
} else {
|
|
860
|
-
|
|
861
|
-
|
|
1233
|
+
_this4._conversationPartialMessage.content = text;
|
|
1234
|
+
_this4._conversationPartialMessage.htmlContent = html;
|
|
862
1235
|
}
|
|
863
|
-
|
|
1236
|
+
_this4.scrollToBottom();
|
|
864
1237
|
}
|
|
865
1238
|
return;
|
|
866
1239
|
}
|
|
867
|
-
if (text && !
|
|
868
|
-
|
|
869
|
-
if (
|
|
870
|
-
|
|
871
|
-
|
|
1240
|
+
if (text && !_this4._audioInputSent) {
|
|
1241
|
+
_this4.prompt = _this4.preRecordingPrompt + text;
|
|
1242
|
+
if (_this4.inputElement) {
|
|
1243
|
+
_this4.inputElement.value = _this4.prompt;
|
|
1244
|
+
_this4.inputElement.dispatchEvent(new Event('input'));
|
|
872
1245
|
}
|
|
873
1246
|
}
|
|
874
1247
|
});
|
|
875
|
-
|
|
1248
|
+
_this4.connection.on("ReceiveConversationUserMessage", function (sessionId, text) {
|
|
876
1249
|
if (text) {
|
|
877
|
-
|
|
1250
|
+
_this4.stopAudio();
|
|
878
1251
|
|
|
879
1252
|
// If there's an interrupted assistant message still streaming,
|
|
880
1253
|
// mark it as done to stop the spinner animation.
|
|
881
|
-
if (
|
|
882
|
-
var oldMsg =
|
|
1254
|
+
if (_this4._conversationAssistantMessage) {
|
|
1255
|
+
var oldMsg = _this4.messages[_this4._conversationAssistantMessage.index];
|
|
883
1256
|
if (oldMsg) {
|
|
884
1257
|
oldMsg.isStreaming = false;
|
|
885
1258
|
}
|
|
886
|
-
|
|
1259
|
+
_this4._conversationAssistantMessage = null;
|
|
887
1260
|
}
|
|
888
1261
|
|
|
889
1262
|
// Replace the partial transcript message with the final one.
|
|
890
|
-
if (
|
|
1263
|
+
if (_this4._conversationPartialMessage) {
|
|
891
1264
|
var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1265
|
+
_this4._conversationPartialMessage.content = text;
|
|
1266
|
+
_this4._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';
|
|
1267
|
+
_this4._conversationPartialMessage.isPartial = false;
|
|
1268
|
+
_this4._conversationPartialMessage = null;
|
|
896
1269
|
} else {
|
|
897
|
-
|
|
1270
|
+
_this4.addMessage({
|
|
898
1271
|
role: 'user',
|
|
899
1272
|
content: text
|
|
900
1273
|
});
|
|
901
1274
|
}
|
|
902
|
-
|
|
1275
|
+
_this4.scrollToBottom();
|
|
903
1276
|
}
|
|
904
1277
|
});
|
|
905
|
-
|
|
906
|
-
if (!
|
|
907
|
-
|
|
908
|
-
|
|
1278
|
+
_this4.connection.on("ReceiveConversationAssistantToken", function (sessionId, messageId, token, responseId, appearance) {
|
|
1279
|
+
if (!_this4._conversationAssistantMessage) {
|
|
1280
|
+
_this4.stopAudio();
|
|
1281
|
+
_this4.hideTypingIndicator();
|
|
909
1282
|
|
|
910
1283
|
// Ensure no stale streaming indicators remain from prior messages.
|
|
911
|
-
for (var j = 0; j <
|
|
912
|
-
if (
|
|
913
|
-
|
|
1284
|
+
for (var j = 0; j < _this4.messages.length; j++) {
|
|
1285
|
+
if (_this4.messages[j].isStreaming) {
|
|
1286
|
+
_this4.messages[j].isStreaming = false;
|
|
914
1287
|
}
|
|
915
1288
|
}
|
|
916
|
-
var msgIndex =
|
|
1289
|
+
var msgIndex = _this4.messages.length;
|
|
917
1290
|
var newMessage = {
|
|
918
1291
|
id: messageId,
|
|
919
1292
|
role: "assistant",
|
|
@@ -921,72 +1294,72 @@ window.openAIChatManager = function () {
|
|
|
921
1294
|
htmlContent: "",
|
|
922
1295
|
isStreaming: true,
|
|
923
1296
|
userRating: null,
|
|
924
|
-
appearance:
|
|
1297
|
+
appearance: _this4.normalizeAssistantAppearance(appearance)
|
|
925
1298
|
};
|
|
926
|
-
|
|
927
|
-
|
|
1299
|
+
_this4.messages.push(newMessage);
|
|
1300
|
+
_this4._conversationAssistantMessage = {
|
|
928
1301
|
index: msgIndex,
|
|
929
1302
|
content: ''
|
|
930
1303
|
};
|
|
931
1304
|
}
|
|
932
|
-
|
|
933
|
-
var msg =
|
|
1305
|
+
_this4._conversationAssistantMessage.content += token;
|
|
1306
|
+
var msg = _this4.messages[_this4._conversationAssistantMessage.index];
|
|
934
1307
|
if (msg) {
|
|
935
1308
|
if (!msg.appearance) {
|
|
936
|
-
msg.appearance =
|
|
1309
|
+
msg.appearance = _this4.normalizeAssistantAppearance(appearance);
|
|
937
1310
|
}
|
|
938
|
-
msg.content =
|
|
1311
|
+
msg.content = _this4._conversationAssistantMessage.content;
|
|
939
1312
|
msg.htmlContent = parseMarkdownContent(msg.content, msg);
|
|
940
|
-
|
|
1313
|
+
_this4.$nextTick(function () {
|
|
941
1314
|
renderChartsInMessage(msg);
|
|
942
|
-
|
|
1315
|
+
_this4.scrollToBottom();
|
|
943
1316
|
});
|
|
944
1317
|
}
|
|
945
1318
|
});
|
|
946
|
-
|
|
947
|
-
if (
|
|
948
|
-
var msg =
|
|
1319
|
+
_this4.connection.on("ReceiveConversationAssistantComplete", function (sessionId, messageId) {
|
|
1320
|
+
if (_this4._conversationAssistantMessage) {
|
|
1321
|
+
var msg = _this4.messages[_this4._conversationAssistantMessage.index];
|
|
949
1322
|
if (msg) {
|
|
950
1323
|
msg.isStreaming = false;
|
|
951
1324
|
}
|
|
952
|
-
|
|
1325
|
+
_this4._conversationAssistantMessage = null;
|
|
953
1326
|
}
|
|
954
1327
|
});
|
|
955
|
-
|
|
1328
|
+
_this4.connection.on("ReceiveAudioChunk", function (sessionId, base64Audio, contentType) {
|
|
956
1329
|
if (base64Audio) {
|
|
957
1330
|
var binaryString = atob(base64Audio);
|
|
958
1331
|
var bytes = new Uint8Array(binaryString.length);
|
|
959
1332
|
for (var i = 0; i < binaryString.length; i++) {
|
|
960
1333
|
bytes[i] = binaryString.charCodeAt(i);
|
|
961
1334
|
}
|
|
962
|
-
|
|
1335
|
+
_this4.audioChunks.push(bytes);
|
|
963
1336
|
}
|
|
964
1337
|
});
|
|
965
|
-
|
|
966
|
-
|
|
1338
|
+
_this4.connection.on("ReceiveAudioComplete", function (sessionId) {
|
|
1339
|
+
_this4.playCollectedAudio();
|
|
967
1340
|
});
|
|
968
|
-
|
|
969
|
-
|
|
1341
|
+
_this4.connection.on("ReceiveNotification", function (notification) {
|
|
1342
|
+
_this4.receiveNotification(notification);
|
|
970
1343
|
});
|
|
971
|
-
|
|
972
|
-
|
|
1344
|
+
_this4.connection.on("UpdateNotification", function (notification) {
|
|
1345
|
+
_this4.updateNotification(notification);
|
|
973
1346
|
});
|
|
974
|
-
|
|
975
|
-
|
|
1347
|
+
_this4.connection.on("RemoveNotification", function (notificationType) {
|
|
1348
|
+
_this4.removeNotification(notificationType);
|
|
976
1349
|
});
|
|
977
|
-
|
|
1350
|
+
_this4.connection.onreconnecting(function () {
|
|
978
1351
|
console.warn("SignalR: reconnecting...");
|
|
979
1352
|
});
|
|
980
|
-
|
|
1353
|
+
_this4.connection.onreconnected(function () {
|
|
981
1354
|
console.info("SignalR: reconnected.");
|
|
982
|
-
if (
|
|
983
|
-
|
|
1355
|
+
if (_this4.isSessionStarted) {
|
|
1356
|
+
_this4.reloadCurrentSession();
|
|
984
1357
|
} else if (config.autoCreateSession) {
|
|
985
|
-
|
|
1358
|
+
_this4.startNewSession();
|
|
986
1359
|
}
|
|
987
1360
|
});
|
|
988
|
-
|
|
989
|
-
if (
|
|
1361
|
+
_this4.connection.onclose(function (error) {
|
|
1362
|
+
if (_this4.isNavigatingAway) {
|
|
990
1363
|
return;
|
|
991
1364
|
}
|
|
992
1365
|
if (error) {
|
|
@@ -995,7 +1368,7 @@ window.openAIChatManager = function () {
|
|
|
995
1368
|
});
|
|
996
1369
|
_context3.p = 1;
|
|
997
1370
|
_context3.n = 2;
|
|
998
|
-
return
|
|
1371
|
+
return _this4.connection.start();
|
|
999
1372
|
case 2:
|
|
1000
1373
|
_context3.n = 4;
|
|
1001
1374
|
break;
|
|
@@ -1010,7 +1383,7 @@ window.openAIChatManager = function () {
|
|
|
1010
1383
|
}))();
|
|
1011
1384
|
},
|
|
1012
1385
|
addMessageInternal: function addMessageInternal(message) {
|
|
1013
|
-
var
|
|
1386
|
+
var _this5 = this;
|
|
1014
1387
|
if (message.role === 'assistant') {
|
|
1015
1388
|
message.appearance = this.normalizeAssistantAppearance(message.appearance);
|
|
1016
1389
|
}
|
|
@@ -1024,7 +1397,7 @@ window.openAIChatManager = function () {
|
|
|
1024
1397
|
}));
|
|
1025
1398
|
this.messages.push(message);
|
|
1026
1399
|
this.$nextTick(function () {
|
|
1027
|
-
|
|
1400
|
+
_this5.fireEvent(new CustomEvent("addedOpenAIPromotMessage", {
|
|
1028
1401
|
detail: {
|
|
1029
1402
|
message: message
|
|
1030
1403
|
}
|
|
@@ -1032,7 +1405,7 @@ window.openAIChatManager = function () {
|
|
|
1032
1405
|
});
|
|
1033
1406
|
},
|
|
1034
1407
|
addMessage: function addMessage(message) {
|
|
1035
|
-
var
|
|
1408
|
+
var _this6 = this;
|
|
1036
1409
|
// Ensure userRating is always defined for Vue reactivity.
|
|
1037
1410
|
if (message.userRating === undefined) {
|
|
1038
1411
|
message.userRating = null;
|
|
@@ -1120,17 +1493,17 @@ window.openAIChatManager = function () {
|
|
|
1120
1493
|
this.$nextTick(function () {
|
|
1121
1494
|
// Render any pending charts once the DOM is updated
|
|
1122
1495
|
renderChartsInMessage(message);
|
|
1123
|
-
|
|
1496
|
+
_this6.scrollToBottom();
|
|
1124
1497
|
});
|
|
1125
1498
|
},
|
|
1126
1499
|
addMessages: function addMessages(messages) {
|
|
1127
|
-
var
|
|
1500
|
+
var _this7 = this;
|
|
1128
1501
|
for (var i = 0; i < messages.length; i++) {
|
|
1129
1502
|
this.addMessageInternal(messages[i]);
|
|
1130
1503
|
}
|
|
1131
1504
|
this.hidePlaceholder();
|
|
1132
1505
|
this.$nextTick(function () {
|
|
1133
|
-
|
|
1506
|
+
_this7.scrollToBottom();
|
|
1134
1507
|
});
|
|
1135
1508
|
},
|
|
1136
1509
|
hidePlaceholder: function hidePlaceholder() {
|
|
@@ -1207,7 +1580,7 @@ window.openAIChatManager = function () {
|
|
|
1207
1580
|
this.prompt = '';
|
|
1208
1581
|
},
|
|
1209
1582
|
startRecording: function startRecording() {
|
|
1210
|
-
var
|
|
1583
|
+
var _this8 = this;
|
|
1211
1584
|
if (this.isRecording || !this.connection) {
|
|
1212
1585
|
return;
|
|
1213
1586
|
}
|
|
@@ -1219,17 +1592,17 @@ window.openAIChatManager = function () {
|
|
|
1219
1592
|
}
|
|
1220
1593
|
}).then(function (stream) {
|
|
1221
1594
|
var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus') ? 'audio/ogg;codecs=opus' : MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
|
|
1222
|
-
|
|
1595
|
+
_this8.mediaRecorder = new MediaRecorder(stream, {
|
|
1223
1596
|
mimeType: mimeType,
|
|
1224
1597
|
audioBitsPerSecond: 128000
|
|
1225
1598
|
});
|
|
1226
|
-
|
|
1227
|
-
|
|
1599
|
+
_this8.preRecordingPrompt = _this8.prompt;
|
|
1600
|
+
_this8._audioInputSent = false;
|
|
1228
1601
|
var subject = new signalR.Subject();
|
|
1229
|
-
var profileId =
|
|
1230
|
-
var sessionId =
|
|
1602
|
+
var profileId = _this8.getProfileId();
|
|
1603
|
+
var sessionId = _this8.getSessionId() || '';
|
|
1231
1604
|
var pendingChunk = Promise.resolve();
|
|
1232
|
-
|
|
1605
|
+
_this8.mediaRecorder.addEventListener('dataavailable', function (e) {
|
|
1233
1606
|
if (e.data && e.data.size > 0) {
|
|
1234
1607
|
pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
1235
1608
|
var data, uint8Array, binaryString, base64;
|
|
@@ -1253,7 +1626,7 @@ window.openAIChatManager = function () {
|
|
|
1253
1626
|
})));
|
|
1254
1627
|
}
|
|
1255
1628
|
});
|
|
1256
|
-
|
|
1629
|
+
_this8.mediaRecorder.addEventListener('stop', function () {
|
|
1257
1630
|
stream.getTracks().forEach(function (track) {
|
|
1258
1631
|
return track.stop();
|
|
1259
1632
|
});
|
|
@@ -1262,10 +1635,10 @@ window.openAIChatManager = function () {
|
|
|
1262
1635
|
});
|
|
1263
1636
|
});
|
|
1264
1637
|
var language = navigator.language || document.documentElement.lang || 'en-US';
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1638
|
+
_this8.connection.send("SendAudioStream", profileId, sessionId, subject, mimeType, language);
|
|
1639
|
+
_this8.mediaRecorder.start(250);
|
|
1640
|
+
_this8.isRecording = true;
|
|
1641
|
+
_this8.updateMicButton();
|
|
1269
1642
|
})["catch"](function (err) {
|
|
1270
1643
|
console.error('Microphone access denied:', err);
|
|
1271
1644
|
});
|
|
@@ -1298,7 +1671,7 @@ window.openAIChatManager = function () {
|
|
|
1298
1671
|
}
|
|
1299
1672
|
},
|
|
1300
1673
|
streamMessage: function streamMessage(profileId, trimmedPrompt, sessionProfileId) {
|
|
1301
|
-
var
|
|
1674
|
+
var _this9 = this;
|
|
1302
1675
|
if (this.stream) {
|
|
1303
1676
|
this.stream.dispose();
|
|
1304
1677
|
this.stream = null;
|
|
@@ -1315,14 +1688,14 @@ window.openAIChatManager = function () {
|
|
|
1315
1688
|
var currentSessionId = this.getSessionId();
|
|
1316
1689
|
this.stream = this.connection.stream("SendMessage", profileId, trimmedPrompt, currentSessionId, sessionProfileId).subscribe({
|
|
1317
1690
|
next: function next(chunk) {
|
|
1318
|
-
var message =
|
|
1691
|
+
var message = _this9.messages[messageIndex];
|
|
1319
1692
|
if (!message) {
|
|
1320
1693
|
if (chunk.sessionId && !currentSessionId) {
|
|
1321
|
-
|
|
1694
|
+
_this9.initializeSession(chunk.sessionId);
|
|
1322
1695
|
}
|
|
1323
|
-
|
|
1696
|
+
_this9.hideTypingIndicator();
|
|
1324
1697
|
// Re-assign the index after hiding the typing indicator.
|
|
1325
|
-
messageIndex =
|
|
1698
|
+
messageIndex = _this9.messages.length;
|
|
1326
1699
|
var newMessage = {
|
|
1327
1700
|
id: chunk.messageId,
|
|
1328
1701
|
role: "assistant",
|
|
@@ -1332,7 +1705,7 @@ window.openAIChatManager = function () {
|
|
|
1332
1705
|
isStreaming: true,
|
|
1333
1706
|
userRating: null
|
|
1334
1707
|
};
|
|
1335
|
-
|
|
1708
|
+
_this9.messages.push(newMessage);
|
|
1336
1709
|
message = newMessage;
|
|
1337
1710
|
}
|
|
1338
1711
|
if (chunk.title && (!message.title || message.title !== chunk.title)) {
|
|
@@ -1372,46 +1745,46 @@ window.openAIChatManager = function () {
|
|
|
1372
1745
|
// Update the existing message
|
|
1373
1746
|
message.content = content;
|
|
1374
1747
|
message.htmlContent = parseMarkdownContent(content, message);
|
|
1375
|
-
|
|
1376
|
-
|
|
1748
|
+
_this9.messages[messageIndex] = message;
|
|
1749
|
+
_this9.$nextTick(function () {
|
|
1377
1750
|
renderChartsInMessage(message);
|
|
1378
|
-
|
|
1751
|
+
_this9.scrollToBottom();
|
|
1379
1752
|
});
|
|
1380
1753
|
},
|
|
1381
1754
|
complete: function complete() {
|
|
1382
|
-
var
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
var msg =
|
|
1755
|
+
var _this9$stream;
|
|
1756
|
+
_this9.processReferences(references, messageIndex);
|
|
1757
|
+
_this9.streamingFinished();
|
|
1758
|
+
var msg = _this9.messages[messageIndex];
|
|
1386
1759
|
if (msg) {
|
|
1387
1760
|
msg.isStreaming = false;
|
|
1388
1761
|
}
|
|
1389
1762
|
if (!msg || !msg.content) {
|
|
1390
1763
|
// No content received at all.
|
|
1391
|
-
|
|
1764
|
+
_this9.hideTypingIndicator();
|
|
1392
1765
|
}
|
|
1393
1766
|
|
|
1394
1767
|
// Trigger text-to-speech only in conversation mode.
|
|
1395
|
-
if (
|
|
1396
|
-
|
|
1768
|
+
if (_this9.isConversationMode && _this9.textToSpeechEnabled && msg && msg.content) {
|
|
1769
|
+
_this9.synthesizeSpeech(msg.content);
|
|
1397
1770
|
}
|
|
1398
|
-
(
|
|
1399
|
-
|
|
1771
|
+
(_this9$stream = _this9.stream) === null || _this9$stream === void 0 || _this9$stream.dispose();
|
|
1772
|
+
_this9.stream = null;
|
|
1400
1773
|
},
|
|
1401
1774
|
error: function error(err) {
|
|
1402
|
-
var
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
var msg =
|
|
1775
|
+
var _this9$stream2;
|
|
1776
|
+
_this9.processReferences(references, messageIndex);
|
|
1777
|
+
_this9.streamingFinished();
|
|
1778
|
+
var msg = _this9.messages[messageIndex];
|
|
1406
1779
|
if (msg) {
|
|
1407
1780
|
msg.isStreaming = false;
|
|
1408
1781
|
}
|
|
1409
|
-
|
|
1410
|
-
if (!
|
|
1411
|
-
|
|
1782
|
+
_this9.hideTypingIndicator();
|
|
1783
|
+
if (!_this9.isNavigatingAway) {
|
|
1784
|
+
_this9.addMessage(_this9.getServiceDownMessage());
|
|
1412
1785
|
}
|
|
1413
|
-
(
|
|
1414
|
-
|
|
1786
|
+
(_this9$stream2 = _this9.stream) === null || _this9$stream2 === void 0 || _this9$stream2.dispose();
|
|
1787
|
+
_this9.stream = null;
|
|
1415
1788
|
console.error("Stream error:", err);
|
|
1416
1789
|
}
|
|
1417
1790
|
});
|
|
@@ -1425,7 +1798,7 @@ window.openAIChatManager = function () {
|
|
|
1425
1798
|
return newMessage;
|
|
1426
1799
|
},
|
|
1427
1800
|
processReferences: function processReferences(references, messageIndex) {
|
|
1428
|
-
var
|
|
1801
|
+
var _this0 = this;
|
|
1429
1802
|
references = normalizeReferences(references);
|
|
1430
1803
|
if (Object.keys(references).length) {
|
|
1431
1804
|
var message = this.messages[messageIndex];
|
|
@@ -1510,7 +1883,7 @@ window.openAIChatManager = function () {
|
|
|
1510
1883
|
this.messages[messageIndex] = message;
|
|
1511
1884
|
this.$nextTick(function () {
|
|
1512
1885
|
renderChartsInMessage(message);
|
|
1513
|
-
|
|
1886
|
+
_this0.scrollToBottom();
|
|
1514
1887
|
});
|
|
1515
1888
|
}
|
|
1516
1889
|
},
|
|
@@ -1553,8 +1926,15 @@ window.openAIChatManager = function () {
|
|
|
1553
1926
|
}
|
|
1554
1927
|
}
|
|
1555
1928
|
},
|
|
1929
|
+
handleExternalTtsStop: function handleExternalTtsStop(e) {
|
|
1930
|
+
var _e$detail;
|
|
1931
|
+
if ((e === null || e === void 0 || (_e$detail = e.detail) === null || _e$detail === void 0 ? void 0 : _e$detail.sourceId) === this.ttsInstanceId) {
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1934
|
+
this.stopAudio(false);
|
|
1935
|
+
},
|
|
1556
1936
|
synthesizeSpeech: function synthesizeSpeech(text, cacheIndex) {
|
|
1557
|
-
var
|
|
1937
|
+
var _this1 = this;
|
|
1558
1938
|
if (!this.textToSpeechEnabled || !text || !this.connection) {
|
|
1559
1939
|
return;
|
|
1560
1940
|
}
|
|
@@ -1563,9 +1943,9 @@ window.openAIChatManager = function () {
|
|
|
1563
1943
|
this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;
|
|
1564
1944
|
this.connection.invoke("SynthesizeSpeech", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)["catch"](function (err) {
|
|
1565
1945
|
console.error("TTS synthesis error:", err);
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1946
|
+
_this1.isPlayingAudio = false;
|
|
1947
|
+
_this1.ttsPlayingMessageIndex = -1;
|
|
1948
|
+
_this1._ttsCacheIndex = -1;
|
|
1569
1949
|
});
|
|
1570
1950
|
},
|
|
1571
1951
|
toggleMessageTts: function toggleMessageTts(message, index) {
|
|
@@ -1573,7 +1953,12 @@ window.openAIChatManager = function () {
|
|
|
1573
1953
|
this.stopAudio();
|
|
1574
1954
|
return;
|
|
1575
1955
|
}
|
|
1576
|
-
this.stopAudio();
|
|
1956
|
+
this.stopAudio(false);
|
|
1957
|
+
window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {
|
|
1958
|
+
detail: {
|
|
1959
|
+
sourceId: this.ttsInstanceId
|
|
1960
|
+
}
|
|
1961
|
+
}));
|
|
1577
1962
|
this.ttsPlayingMessageIndex = index;
|
|
1578
1963
|
if (this.ttsAudioCache[index]) {
|
|
1579
1964
|
this.playAudioBlob(this.ttsAudioCache[index]);
|
|
@@ -1585,6 +1970,7 @@ window.openAIChatManager = function () {
|
|
|
1585
1970
|
if (this.audioChunks.length === 0) {
|
|
1586
1971
|
if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {
|
|
1587
1972
|
this.isPlayingAudio = false;
|
|
1973
|
+
this.ttsPlayingMessageIndex = -1;
|
|
1588
1974
|
}
|
|
1589
1975
|
return;
|
|
1590
1976
|
}
|
|
@@ -1623,26 +2009,32 @@ window.openAIChatManager = function () {
|
|
|
1623
2009
|
this.playAudioBlob(blob);
|
|
1624
2010
|
},
|
|
1625
2011
|
playAudioBlob: function playAudioBlob(blob) {
|
|
1626
|
-
var
|
|
2012
|
+
var _this10 = this;
|
|
1627
2013
|
var url = URL.createObjectURL(blob);
|
|
1628
2014
|
var audio = new Audio(url);
|
|
2015
|
+
this.currentAudioUrl = url;
|
|
1629
2016
|
this.currentAudioElement = audio;
|
|
1630
2017
|
this.isPlayingAudio = true;
|
|
1631
2018
|
audio.addEventListener('ended', function () {
|
|
2019
|
+
_this10.currentAudioElement = null;
|
|
2020
|
+
_this10.currentAudioUrl = null;
|
|
1632
2021
|
URL.revokeObjectURL(url);
|
|
1633
|
-
|
|
1634
|
-
_this1.playNextInQueue();
|
|
2022
|
+
_this10.playNextInQueue();
|
|
1635
2023
|
});
|
|
1636
2024
|
audio.addEventListener('error', function () {
|
|
2025
|
+
_this10.currentAudioElement = null;
|
|
2026
|
+
_this10.currentAudioUrl = null;
|
|
1637
2027
|
URL.revokeObjectURL(url);
|
|
1638
|
-
|
|
1639
|
-
_this1.playNextInQueue();
|
|
2028
|
+
_this10.playNextInQueue();
|
|
1640
2029
|
});
|
|
1641
2030
|
audio.play()["catch"](function (err) {
|
|
1642
2031
|
console.error("Audio playback error:", err);
|
|
2032
|
+
_this10.currentAudioElement = null;
|
|
2033
|
+
_this10.currentAudioUrl = null;
|
|
1643
2034
|
URL.revokeObjectURL(url);
|
|
1644
|
-
|
|
1645
|
-
|
|
2035
|
+
_this10.audioPlayQueue = [];
|
|
2036
|
+
_this10.isPlayingAudio = false;
|
|
2037
|
+
_this10.ttsPlayingMessageIndex = -1;
|
|
1646
2038
|
});
|
|
1647
2039
|
},
|
|
1648
2040
|
playNextInQueue: function playNextInQueue() {
|
|
@@ -1661,6 +2053,10 @@ window.openAIChatManager = function () {
|
|
|
1661
2053
|
this.currentAudioElement.currentTime = 0;
|
|
1662
2054
|
this.currentAudioElement = null;
|
|
1663
2055
|
}
|
|
2056
|
+
if (this.currentAudioUrl) {
|
|
2057
|
+
URL.revokeObjectURL(this.currentAudioUrl);
|
|
2058
|
+
this.currentAudioUrl = null;
|
|
2059
|
+
}
|
|
1664
2060
|
this.audioChunks = [];
|
|
1665
2061
|
this.audioPlayQueue = [];
|
|
1666
2062
|
this.isPlayingAudio = false;
|
|
@@ -1674,7 +2070,7 @@ window.openAIChatManager = function () {
|
|
|
1674
2070
|
}
|
|
1675
2071
|
},
|
|
1676
2072
|
startConversationMode: function startConversationMode() {
|
|
1677
|
-
var
|
|
2073
|
+
var _this11 = this;
|
|
1678
2074
|
if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {
|
|
1679
2075
|
return;
|
|
1680
2076
|
}
|
|
@@ -1694,12 +2090,12 @@ window.openAIChatManager = function () {
|
|
|
1694
2090
|
}
|
|
1695
2091
|
}).then(function (stream) {
|
|
1696
2092
|
var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus') ? 'audio/ogg;codecs=opus' : MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
|
|
1697
|
-
|
|
2093
|
+
_this11.mediaRecorder = new MediaRecorder(stream, {
|
|
1698
2094
|
mimeType: mimeType,
|
|
1699
2095
|
audioBitsPerSecond: 128000
|
|
1700
2096
|
});
|
|
1701
|
-
|
|
1702
|
-
|
|
2097
|
+
_this11._conversationSubject = new signalR.Subject();
|
|
2098
|
+
_this11._conversationStream = stream;
|
|
1703
2099
|
|
|
1704
2100
|
// Create an AnalyserNode for volume-based interrupt detection.
|
|
1705
2101
|
// During TTS playback, detect when the user speaks above
|
|
@@ -1708,20 +2104,20 @@ window.openAIChatManager = function () {
|
|
|
1708
2104
|
// speaker echo so the STT stream has no gaps.
|
|
1709
2105
|
var AudioCtx = window.AudioContext || window.webkitAudioContext;
|
|
1710
2106
|
if (AudioCtx) {
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
var micSource =
|
|
1715
|
-
micSource.connect(
|
|
2107
|
+
_this11._conversationAudioCtx = new AudioCtx();
|
|
2108
|
+
_this11._conversationAnalyser = _this11._conversationAudioCtx.createAnalyser();
|
|
2109
|
+
_this11._conversationAnalyser.fftSize = 256;
|
|
2110
|
+
var micSource = _this11._conversationAudioCtx.createMediaStreamSource(stream);
|
|
2111
|
+
micSource.connect(_this11._conversationAnalyser);
|
|
1716
2112
|
}
|
|
1717
2113
|
var pendingChunk = Promise.resolve();
|
|
1718
|
-
var analyser =
|
|
2114
|
+
var analyser = _this11._conversationAnalyser;
|
|
1719
2115
|
var interruptVolumeThreshold = 30;
|
|
1720
|
-
|
|
2116
|
+
_this11.mediaRecorder.addEventListener('dataavailable', function (e) {
|
|
1721
2117
|
if (e.data && e.data.size > 0) {
|
|
1722
2118
|
// During TTS playback, check mic volume to detect
|
|
1723
2119
|
// user interruption (speaking above threshold).
|
|
1724
|
-
if (
|
|
2120
|
+
if (_this11.isPlayingAudio && analyser) {
|
|
1725
2121
|
var freqData = new Uint8Array(analyser.frequencyBinCount);
|
|
1726
2122
|
analyser.getByteFrequencyData(freqData);
|
|
1727
2123
|
var sum = 0;
|
|
@@ -1731,7 +2127,7 @@ window.openAIChatManager = function () {
|
|
|
1731
2127
|
var avg = sum / freqData.length;
|
|
1732
2128
|
if (avg >= interruptVolumeThreshold) {
|
|
1733
2129
|
// User is speaking — interrupt TTS playback.
|
|
1734
|
-
|
|
2130
|
+
_this11.stopAudio();
|
|
1735
2131
|
}
|
|
1736
2132
|
}
|
|
1737
2133
|
|
|
@@ -1753,7 +2149,7 @@ window.openAIChatManager = function () {
|
|
|
1753
2149
|
}, '');
|
|
1754
2150
|
base64 = btoa(binaryString);
|
|
1755
2151
|
try {
|
|
1756
|
-
|
|
2152
|
+
_this11._conversationSubject.next(base64);
|
|
1757
2153
|
} catch (err) {
|
|
1758
2154
|
// Subject may have been completed already.
|
|
1759
2155
|
}
|
|
@@ -1764,28 +2160,28 @@ window.openAIChatManager = function () {
|
|
|
1764
2160
|
})));
|
|
1765
2161
|
}
|
|
1766
2162
|
});
|
|
1767
|
-
|
|
2163
|
+
_this11.mediaRecorder.addEventListener('stop', function () {
|
|
1768
2164
|
stream.getTracks().forEach(function (track) {
|
|
1769
2165
|
return track.stop();
|
|
1770
2166
|
});
|
|
1771
2167
|
pendingChunk.then(function () {
|
|
1772
2168
|
try {
|
|
1773
|
-
|
|
2169
|
+
_this11._conversationSubject.complete();
|
|
1774
2170
|
} catch (err) {
|
|
1775
2171
|
// Already completed.
|
|
1776
2172
|
}
|
|
1777
2173
|
});
|
|
1778
2174
|
});
|
|
1779
|
-
var profileId =
|
|
1780
|
-
var sessionId =
|
|
2175
|
+
var profileId = _this11.getProfileId();
|
|
2176
|
+
var sessionId = _this11.getSessionId() || '';
|
|
1781
2177
|
var language = navigator.language || document.documentElement.lang || 'en-US';
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
2178
|
+
_this11.connection.send("StartConversation", profileId, sessionId, _this11._conversationSubject, mimeType, language);
|
|
2179
|
+
_this11.mediaRecorder.start(250);
|
|
2180
|
+
_this11.isRecording = true;
|
|
1785
2181
|
})["catch"](function (err) {
|
|
1786
2182
|
console.error('Microphone access denied:', err);
|
|
1787
|
-
|
|
1788
|
-
|
|
2183
|
+
_this11.isConversationMode = false;
|
|
2184
|
+
_this11.updateConversationButton();
|
|
1789
2185
|
});
|
|
1790
2186
|
},
|
|
1791
2187
|
stopConversationMode: function stopConversationMode() {
|
|
@@ -1912,7 +2308,7 @@ window.openAIChatManager = function () {
|
|
|
1912
2308
|
return removedCount;
|
|
1913
2309
|
},
|
|
1914
2310
|
receiveNotification: function receiveNotification(notification) {
|
|
1915
|
-
var
|
|
2311
|
+
var _this12 = this;
|
|
1916
2312
|
if (!notification || !notification.type) {
|
|
1917
2313
|
return;
|
|
1918
2314
|
}
|
|
@@ -1927,7 +2323,7 @@ window.openAIChatManager = function () {
|
|
|
1927
2323
|
}
|
|
1928
2324
|
this.scheduleNotificationDismiss(notification);
|
|
1929
2325
|
this.$nextTick(function () {
|
|
1930
|
-
|
|
2326
|
+
_this12.scrollToBottom();
|
|
1931
2327
|
});
|
|
1932
2328
|
},
|
|
1933
2329
|
updateNotification: function updateNotification(notification) {
|
|
@@ -1944,12 +2340,12 @@ window.openAIChatManager = function () {
|
|
|
1944
2340
|
}
|
|
1945
2341
|
},
|
|
1946
2342
|
scheduleNotificationDismiss: function scheduleNotificationDismiss(notification) {
|
|
1947
|
-
var
|
|
2343
|
+
var _this13 = this;
|
|
1948
2344
|
if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {
|
|
1949
2345
|
return;
|
|
1950
2346
|
}
|
|
1951
2347
|
this.notificationDismissTimers[notification.type] = setTimeout(function () {
|
|
1952
|
-
|
|
2348
|
+
_this13.removeNotification(notification.type);
|
|
1953
2349
|
}, notification.autoDismissMs);
|
|
1954
2350
|
},
|
|
1955
2351
|
clearNotificationDismiss: function clearNotificationDismiss(notificationType) {
|
|
@@ -1979,12 +2375,12 @@ window.openAIChatManager = function () {
|
|
|
1979
2375
|
});
|
|
1980
2376
|
},
|
|
1981
2377
|
scrollToBottom: function scrollToBottom() {
|
|
1982
|
-
var
|
|
2378
|
+
var _this14 = this;
|
|
1983
2379
|
if (!this.autoScroll) {
|
|
1984
2380
|
return;
|
|
1985
2381
|
}
|
|
1986
2382
|
setTimeout(function () {
|
|
1987
|
-
|
|
2383
|
+
_this14.chatContainer.scrollTop = _this14.chatContainer.scrollHeight - _this14.chatContainer.clientHeight;
|
|
1988
2384
|
}, 50);
|
|
1989
2385
|
},
|
|
1990
2386
|
handleUserInput: function handleUserInput(event) {
|
|
@@ -2026,16 +2422,16 @@ window.openAIChatManager = function () {
|
|
|
2026
2422
|
});
|
|
2027
2423
|
},
|
|
2028
2424
|
initializeApp: function initializeApp() {
|
|
2029
|
-
var
|
|
2425
|
+
var _this15 = this;
|
|
2030
2426
|
this.inputElement = document.querySelector(config.inputElementSelector);
|
|
2031
2427
|
this.buttonElement = document.querySelector(config.sendButtonElementSelector);
|
|
2032
2428
|
this.chatContainer = document.querySelector(config.chatContainerElementSelector);
|
|
2033
2429
|
this.placeholder = document.querySelector(config.placeholderElementSelector);
|
|
2034
2430
|
this.applyOrchestratorAvailability();
|
|
2035
2431
|
var sessionId = this.getSessionId();
|
|
2036
|
-
if (!
|
|
2432
|
+
if (!hasWidgetConfig && sessionId) {
|
|
2037
2433
|
this.loadSession(sessionId);
|
|
2038
|
-
} else if (this.isOrchestratorAvailable() && config.autoCreateSession && !
|
|
2434
|
+
} else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {
|
|
2039
2435
|
this.startNewSession();
|
|
2040
2436
|
}
|
|
2041
2437
|
|
|
@@ -2055,7 +2451,7 @@ window.openAIChatManager = function () {
|
|
|
2055
2451
|
fileInput.accept = config.allowedExtensions;
|
|
2056
2452
|
}
|
|
2057
2453
|
fileInput.addEventListener('change', function (e) {
|
|
2058
|
-
return
|
|
2454
|
+
return _this15.handleFileInputChange(e);
|
|
2059
2455
|
});
|
|
2060
2456
|
this.documentBar.parentElement.appendChild(fileInput);
|
|
2061
2457
|
|
|
@@ -2063,13 +2459,13 @@ window.openAIChatManager = function () {
|
|
|
2063
2459
|
var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;
|
|
2064
2460
|
if (inputArea) {
|
|
2065
2461
|
inputArea.addEventListener('dragover', function (e) {
|
|
2066
|
-
return
|
|
2462
|
+
return _this15.handleDragOver(e);
|
|
2067
2463
|
});
|
|
2068
2464
|
inputArea.addEventListener('dragleave', function (e) {
|
|
2069
|
-
return
|
|
2465
|
+
return _this15.handleDragLeave(e);
|
|
2070
2466
|
});
|
|
2071
2467
|
inputArea.addEventListener('drop', function (e) {
|
|
2072
|
-
return
|
|
2468
|
+
return _this15.handleDrop(e);
|
|
2073
2469
|
});
|
|
2074
2470
|
}
|
|
2075
2471
|
}
|
|
@@ -2077,55 +2473,55 @@ window.openAIChatManager = function () {
|
|
|
2077
2473
|
|
|
2078
2474
|
// Pause auto-scroll when the user manually scrolls up during streaming.
|
|
2079
2475
|
this.chatContainer.addEventListener('scroll', function () {
|
|
2080
|
-
if (!
|
|
2476
|
+
if (!_this15.stream) {
|
|
2081
2477
|
return;
|
|
2082
2478
|
}
|
|
2083
2479
|
var threshold = 30;
|
|
2084
|
-
var atBottom =
|
|
2085
|
-
|
|
2480
|
+
var atBottom = _this15.chatContainer.scrollHeight - _this15.chatContainer.clientHeight - _this15.chatContainer.scrollTop <= threshold;
|
|
2481
|
+
_this15.autoScroll = atBottom;
|
|
2086
2482
|
});
|
|
2087
2483
|
this.inputElement.addEventListener('keydown', function (event) {
|
|
2088
|
-
if (
|
|
2484
|
+
if (_this15.stream != null) {
|
|
2089
2485
|
return;
|
|
2090
2486
|
}
|
|
2091
2487
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
2092
2488
|
event.preventDefault();
|
|
2093
|
-
|
|
2489
|
+
_this15.buttonElement.click();
|
|
2094
2490
|
}
|
|
2095
2491
|
});
|
|
2096
2492
|
this.inputElement.addEventListener('input', function (e) {
|
|
2097
|
-
|
|
2493
|
+
_this15.handleUserInput(e);
|
|
2098
2494
|
if (e.target.value.trim()) {
|
|
2099
|
-
|
|
2495
|
+
_this15.buttonElement.removeAttribute('disabled');
|
|
2100
2496
|
} else {
|
|
2101
|
-
|
|
2497
|
+
_this15.buttonElement.setAttribute('disabled', true);
|
|
2102
2498
|
}
|
|
2103
2499
|
});
|
|
2104
2500
|
this.buttonElement.addEventListener('click', function () {
|
|
2105
|
-
if (
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2501
|
+
if (_this15.stream != null) {
|
|
2502
|
+
_this15.stream.dispose();
|
|
2503
|
+
_this15.stream = null;
|
|
2504
|
+
_this15.streamingFinished();
|
|
2505
|
+
_this15.hideTypingIndicator();
|
|
2110
2506
|
|
|
2111
2507
|
// Clean up: remove empty assistant message or stop streaming animation.
|
|
2112
|
-
if (
|
|
2113
|
-
var lastMsg =
|
|
2508
|
+
if (_this15.messages.length > 0) {
|
|
2509
|
+
var lastMsg = _this15.messages[_this15.messages.length - 1];
|
|
2114
2510
|
if (lastMsg.role === 'assistant' && !lastMsg.content) {
|
|
2115
|
-
|
|
2511
|
+
_this15.messages.pop();
|
|
2116
2512
|
} else if (lastMsg.isStreaming) {
|
|
2117
2513
|
lastMsg.isStreaming = false;
|
|
2118
2514
|
}
|
|
2119
2515
|
}
|
|
2120
2516
|
return;
|
|
2121
2517
|
}
|
|
2122
|
-
|
|
2518
|
+
_this15.sendMessage();
|
|
2123
2519
|
});
|
|
2124
2520
|
var promptGenerators = document.getElementsByClassName('profile-generated-prompt');
|
|
2125
2521
|
for (var i = 0; i < promptGenerators.length; i++) {
|
|
2126
2522
|
promptGenerators[i].addEventListener('click', function (e) {
|
|
2127
2523
|
e.preventDefault();
|
|
2128
|
-
|
|
2524
|
+
_this15.generatePrompt(e.target);
|
|
2129
2525
|
});
|
|
2130
2526
|
}
|
|
2131
2527
|
var chatSessions = document.getElementsByClassName('chat-session-history-item');
|
|
@@ -2137,8 +2533,8 @@ window.openAIChatManager = function () {
|
|
|
2137
2533
|
console.error('an element with the class chat-session-history-item with no data-session-id set.');
|
|
2138
2534
|
return;
|
|
2139
2535
|
}
|
|
2140
|
-
|
|
2141
|
-
|
|
2536
|
+
_this15.loadSession(sessionId);
|
|
2537
|
+
_this15.showChatScreen();
|
|
2142
2538
|
});
|
|
2143
2539
|
}
|
|
2144
2540
|
for (var _i5 = 0; _i5 < config.messages.length; _i5++) {
|
|
@@ -2147,7 +2543,7 @@ window.openAIChatManager = function () {
|
|
|
2147
2543
|
|
|
2148
2544
|
// Update feedback icons in the DOM after initial messages have rendered.
|
|
2149
2545
|
this.$nextTick(function () {
|
|
2150
|
-
|
|
2546
|
+
_this15.refreshAllFeedbackIcons();
|
|
2151
2547
|
});
|
|
2152
2548
|
|
|
2153
2549
|
// Delegate click for code block copy buttons.
|
|
@@ -2179,7 +2575,7 @@ window.openAIChatManager = function () {
|
|
|
2179
2575
|
if (this.micButton) {
|
|
2180
2576
|
this.micButton.style.display = '';
|
|
2181
2577
|
this.micButton.addEventListener('click', function () {
|
|
2182
|
-
|
|
2578
|
+
_this15.toggleRecording();
|
|
2183
2579
|
});
|
|
2184
2580
|
}
|
|
2185
2581
|
}
|
|
@@ -2189,7 +2585,7 @@ window.openAIChatManager = function () {
|
|
|
2189
2585
|
this.conversationButton = document.querySelector(config.conversationButtonElementSelector);
|
|
2190
2586
|
if (this.conversationButton) {
|
|
2191
2587
|
this.conversationButton.addEventListener('click', function () {
|
|
2192
|
-
|
|
2588
|
+
_this15.toggleConversationMode();
|
|
2193
2589
|
});
|
|
2194
2590
|
}
|
|
2195
2591
|
}
|
|
@@ -2221,7 +2617,7 @@ window.openAIChatManager = function () {
|
|
|
2221
2617
|
}
|
|
2222
2618
|
},
|
|
2223
2619
|
initializeWidget: function initializeWidget() {
|
|
2224
|
-
var
|
|
2620
|
+
var _this16 = this;
|
|
2225
2621
|
if (!config.widget.chatWidgetContainer) {
|
|
2226
2622
|
console.error('The widget chatWidgetContainer is required.');
|
|
2227
2623
|
return;
|
|
@@ -2239,7 +2635,51 @@ window.openAIChatManager = function () {
|
|
|
2239
2635
|
}
|
|
2240
2636
|
this.chatWidgetStateName = config.widget.chatWidgetStateName;
|
|
2241
2637
|
this.chatWidgetStateSession = config.widget.chatWidgetStateName + 'Session';
|
|
2638
|
+
this.chatWidgetLayoutKey = config.widget.chatWidgetStateName + 'Layout';
|
|
2639
|
+
this.widgetContainerElement = chatWidgetContainer;
|
|
2640
|
+
this.widgetToggleButtonElement = config.widget.toggleButtonSelector ? document.querySelector(config.widget.toggleButtonSelector) : null;
|
|
2641
|
+
this.widgetResetSizeButtonElement = config.widget.resetSizeButtonSelector ? document.querySelector(config.widget.resetSizeButtonSelector) : null;
|
|
2642
|
+
this.widgetDefaultWidth = parsePixelValue(config.widget.defaultWidth) || parsePixelValue(window.getComputedStyle(chatWidgetContainer).width) || 380;
|
|
2643
|
+
this.widgetDefaultHeight = parsePixelValue(config.widget.defaultHeight) || parsePixelValue(window.getComputedStyle(chatWidgetContainer).height) || 520;
|
|
2242
2644
|
this.widgetIsInitialized = true;
|
|
2645
|
+
if (config.widget.enableResizing) {
|
|
2646
|
+
chatWidgetContainer.classList.add('ai-chat-widget-resizable');
|
|
2647
|
+
chatWidgetContainer.style.minWidth = (parsePixelValue(config.widget.minWidth) || 320) + 'px';
|
|
2648
|
+
chatWidgetContainer.style.minHeight = (parsePixelValue(config.widget.minHeight) || 420) + 'px';
|
|
2649
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
2650
|
+
this.widgetResizeObserver = new ResizeObserver(function () {
|
|
2651
|
+
_this16.persistWidgetPanelSize();
|
|
2652
|
+
_this16.constrainWidgetElementsToViewport();
|
|
2653
|
+
_this16.updateWidgetResetSizeButtonVisibility();
|
|
2654
|
+
});
|
|
2655
|
+
this.widgetResizeObserver.observe(chatWidgetContainer);
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
var dragHandleSelector = config.widget.dragHandleSelector || '.ai-chat-widget-header';
|
|
2659
|
+
var dragHandle = chatWidgetContainer.querySelector(dragHandleSelector);
|
|
2660
|
+
if (config.widget.enableDragging && dragHandle) {
|
|
2661
|
+
dragHandle.classList.add('ai-chat-widget-drag-handle');
|
|
2662
|
+
chatWidgetContainer.classList.add('ai-chat-widget-draggable');
|
|
2663
|
+
this.attachDraggableWidgetElement(chatWidgetContainer, dragHandle, 'panel', false);
|
|
2664
|
+
}
|
|
2665
|
+
if (config.widget.enableDragging && this.widgetToggleButtonElement) {
|
|
2666
|
+
this.widgetToggleButtonElement.classList.add('ai-chat-widget-draggable');
|
|
2667
|
+
this.attachDraggableWidgetElement(this.widgetToggleButtonElement, this.widgetToggleButtonElement, 'toggle', true);
|
|
2668
|
+
}
|
|
2669
|
+
if (this.widgetResetSizeButtonElement) {
|
|
2670
|
+
this.widgetResetSizeButtonElement.addEventListener('click', function (event) {
|
|
2671
|
+
event.preventDefault();
|
|
2672
|
+
_this16.resetWidgetSize();
|
|
2673
|
+
});
|
|
2674
|
+
}
|
|
2675
|
+
this.restoreWidgetLayout();
|
|
2676
|
+
if (!this.widgetViewportResizeHandler) {
|
|
2677
|
+
this.widgetViewportResizeHandler = function () {
|
|
2678
|
+
_this16.constrainWidgetElementsToViewport();
|
|
2679
|
+
_this16.updateWidgetResetSizeButtonVisibility();
|
|
2680
|
+
};
|
|
2681
|
+
window.addEventListener('resize', this.widgetViewportResizeHandler);
|
|
2682
|
+
}
|
|
2243
2683
|
|
|
2244
2684
|
// Auto-load the last session so the user always sees previous chat history.
|
|
2245
2685
|
this.reloadCurrentSession();
|
|
@@ -2250,14 +2690,14 @@ window.openAIChatManager = function () {
|
|
|
2250
2690
|
var showHistoryButton = document.querySelector(config.widget.showHistoryButton);
|
|
2251
2691
|
if (showHistoryButton) {
|
|
2252
2692
|
showHistoryButton.addEventListener('click', function () {
|
|
2253
|
-
|
|
2693
|
+
_this16.chatHistorySection.classList.toggle('show');
|
|
2254
2694
|
});
|
|
2255
2695
|
}
|
|
2256
2696
|
if (config.widget.closeHistoryButton) {
|
|
2257
2697
|
var closeHistoryButton = document.querySelector(config.widget.closeHistoryButton);
|
|
2258
2698
|
if (closeHistoryButton) {
|
|
2259
2699
|
closeHistoryButton.addEventListener('click', function () {
|
|
2260
|
-
|
|
2700
|
+
_this16.showChatScreen();
|
|
2261
2701
|
});
|
|
2262
2702
|
}
|
|
2263
2703
|
}
|
|
@@ -2266,8 +2706,8 @@ window.openAIChatManager = function () {
|
|
|
2266
2706
|
var newChatButton = document.querySelector(config.widget.newChatButton);
|
|
2267
2707
|
if (newChatButton) {
|
|
2268
2708
|
newChatButton.addEventListener('click', function () {
|
|
2269
|
-
|
|
2270
|
-
|
|
2709
|
+
_this16.resetSession();
|
|
2710
|
+
_this16.showChatScreen();
|
|
2271
2711
|
});
|
|
2272
2712
|
}
|
|
2273
2713
|
}
|
|
@@ -2403,17 +2843,17 @@ window.openAIChatManager = function () {
|
|
|
2403
2843
|
}
|
|
2404
2844
|
},
|
|
2405
2845
|
mounted: function mounted() {
|
|
2406
|
-
var
|
|
2846
|
+
var _this17 = this;
|
|
2407
2847
|
_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
|
|
2408
2848
|
return _regenerator().w(function (_context6) {
|
|
2409
2849
|
while (1) switch (_context6.n) {
|
|
2410
2850
|
case 0:
|
|
2411
2851
|
_context6.n = 1;
|
|
2412
|
-
return
|
|
2852
|
+
return _this17.startConnection();
|
|
2413
2853
|
case 1:
|
|
2414
|
-
|
|
2415
|
-
if (
|
|
2416
|
-
|
|
2854
|
+
_this17.initializeApp();
|
|
2855
|
+
if (hasWidgetConfig) {
|
|
2856
|
+
_this17.initializeWidget();
|
|
2417
2857
|
}
|
|
2418
2858
|
case 2:
|
|
2419
2859
|
return _context6.a(2);
|
|
@@ -2421,9 +2861,12 @@ window.openAIChatManager = function () {
|
|
|
2421
2861
|
}, _callee6);
|
|
2422
2862
|
}))();
|
|
2423
2863
|
window.addEventListener('beforeunload', this.handleBeforeUnload);
|
|
2864
|
+
window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);
|
|
2424
2865
|
},
|
|
2425
2866
|
beforeUnmount: function beforeUnmount() {
|
|
2426
2867
|
window.removeEventListener('beforeunload', this.handleBeforeUnload);
|
|
2868
|
+
window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);
|
|
2869
|
+
this.stopAudio(false);
|
|
2427
2870
|
if (this.stream) {
|
|
2428
2871
|
this.stream.dispose();
|
|
2429
2872
|
this.stream = null;
|