@crestapps/ai-chat-ui 1.0.0-preview.10 → 1.0.0-preview.12
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-widget.js +818 -0
- package/dist/ai-chat-widget.js.map +1 -0
- package/dist/ai-chat-widget.min.js +2 -0
- package/dist/ai-chat-widget.min.js.map +1 -0
- package/dist/ai-chat.js +638 -880
- package/dist/ai-chat.js.map +1 -1
- package/dist/ai-chat.min.js +1 -1
- package/dist/ai-chat.min.js.map +1 -1
- package/dist/chat-widget.css +2 -0
- package/dist/chat-widget.css.map +1 -1
- package/dist/chat-widget.min.css +1 -1
- package/package.json +5 -1
package/dist/ai-chat.js
CHANGED
|
@@ -363,6 +363,7 @@ window.openAIChatManager = function () {
|
|
|
363
363
|
var config = Object.assign({}, defaultConfig, instanceConfig);
|
|
364
364
|
config.widget = Object.assign({}, defaultConfig.widget || {}, instanceConfig && instanceConfig.widget ? instanceConfig.widget : {});
|
|
365
365
|
var hasWidgetConfig = !!(instanceConfig && instanceConfig.widget && instanceConfig.widget.chatWidgetContainer && instanceConfig.widget.chatWidgetStateName);
|
|
366
|
+
var widgetBehavior = window.openAIChatWidgetBehavior || null;
|
|
366
367
|
// Keep defaultConfig in sync so renderers use overridden values
|
|
367
368
|
defaultConfig = config;
|
|
368
369
|
if (!config.signalRHubUrl) {
|
|
@@ -385,7 +386,7 @@ window.openAIChatManager = function () {
|
|
|
385
386
|
console.error('The sendButtonElementSelector is required.');
|
|
386
387
|
return;
|
|
387
388
|
}
|
|
388
|
-
var
|
|
389
|
+
var appDefinition = {
|
|
389
390
|
data: function data() {
|
|
390
391
|
return {
|
|
391
392
|
inputElement: null,
|
|
@@ -394,18 +395,6 @@ window.openAIChatManager = function () {
|
|
|
394
395
|
placeholder: null,
|
|
395
396
|
isSessionStarted: false,
|
|
396
397
|
isPlaceholderVisible: true,
|
|
397
|
-
chatWidgetStateName: null,
|
|
398
|
-
chatWidgetStateSession: null,
|
|
399
|
-
chatWidgetLayoutKey: null,
|
|
400
|
-
chatHistorySection: null,
|
|
401
|
-
widgetContainerElement: null,
|
|
402
|
-
widgetToggleButtonElement: null,
|
|
403
|
-
widgetResetSizeButtonElement: null,
|
|
404
|
-
widgetResizeObserver: null,
|
|
405
|
-
widgetViewportResizeHandler: null,
|
|
406
|
-
widgetDefaultWidth: null,
|
|
407
|
-
widgetDefaultHeight: null,
|
|
408
|
-
widgetIsInitialized: false,
|
|
409
398
|
isStreaming: false,
|
|
410
399
|
isNavigatingAway: false,
|
|
411
400
|
autoScroll: true,
|
|
@@ -415,6 +404,8 @@ window.openAIChatManager = function () {
|
|
|
415
404
|
prompt: '',
|
|
416
405
|
documents: config.existingDocuments || [],
|
|
417
406
|
isUploading: false,
|
|
407
|
+
isDocumentOperationPending: false,
|
|
408
|
+
documentOperationQueue: null,
|
|
418
409
|
uploadErrors: [],
|
|
419
410
|
isDragOver: false,
|
|
420
411
|
documentBar: null,
|
|
@@ -444,7 +435,11 @@ window.openAIChatManager = function () {
|
|
|
444
435
|
conversationModeEnabled: config.chatMode === 'Conversation',
|
|
445
436
|
conversationButton: null,
|
|
446
437
|
isConversationMode: false,
|
|
447
|
-
notificationDismissTimers: {}
|
|
438
|
+
notificationDismissTimers: {},
|
|
439
|
+
pendingSessionPromise: null,
|
|
440
|
+
pendingSessionResolver: null,
|
|
441
|
+
pendingSessionRejector: null,
|
|
442
|
+
pendingSessionTimeoutId: null
|
|
448
443
|
};
|
|
449
444
|
},
|
|
450
445
|
computed: {
|
|
@@ -461,336 +456,6 @@ window.openAIChatManager = function () {
|
|
|
461
456
|
handleBeforeUnload: function handleBeforeUnload() {
|
|
462
457
|
this.isNavigatingAway = true;
|
|
463
458
|
},
|
|
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
|
-
},
|
|
794
459
|
handleDragOver: function handleDragOver(e) {
|
|
795
460
|
if (!config.sessionDocumentsEnabled) return;
|
|
796
461
|
e.preventDefault();
|
|
@@ -815,180 +480,272 @@ window.openAIChatManager = function () {
|
|
|
815
480
|
var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;
|
|
816
481
|
if (inputArea) inputArea.classList.remove('ai-chat-drag-over');
|
|
817
482
|
if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
|
818
|
-
this.uploadFiles(e.dataTransfer.files);
|
|
483
|
+
this.uploadFiles(Array.from(e.dataTransfer.files));
|
|
819
484
|
}
|
|
820
485
|
},
|
|
821
486
|
triggerFileInput: function triggerFileInput() {
|
|
822
|
-
if (!config.sessionDocumentsEnabled) return;
|
|
487
|
+
if (!config.sessionDocumentsEnabled || this.isDocumentOperationPending) return;
|
|
823
488
|
var fileInput = document.getElementById('ai-chat-doc-input');
|
|
824
489
|
if (fileInput) fileInput.click();
|
|
825
490
|
},
|
|
826
491
|
handleFileInputChange: function handleFileInputChange(e) {
|
|
827
|
-
var files = e.target.files;
|
|
492
|
+
var files = e.target.files ? Array.from(e.target.files) : [];
|
|
828
493
|
if (files && files.length > 0) {
|
|
829
494
|
this.uploadFiles(files);
|
|
830
495
|
}
|
|
831
496
|
e.target.value = '';
|
|
832
497
|
},
|
|
833
|
-
|
|
834
|
-
var
|
|
835
|
-
|
|
836
|
-
|
|
498
|
+
queueDocumentOperation: function queueDocumentOperation(operation) {
|
|
499
|
+
var self = this;
|
|
500
|
+
var previousOperation = this.documentOperationQueue || Promise.resolve();
|
|
501
|
+
var nextOperation = previousOperation["catch"](function () {}).then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
|
|
837
502
|
return _regenerator().w(function (_context) {
|
|
838
503
|
while (1) switch (_context.p = _context.n) {
|
|
504
|
+
case 0:
|
|
505
|
+
self.isDocumentOperationPending = true;
|
|
506
|
+
_context.p = 1;
|
|
507
|
+
_context.n = 2;
|
|
508
|
+
return operation();
|
|
509
|
+
case 2:
|
|
510
|
+
return _context.a(2, _context.v);
|
|
511
|
+
case 3:
|
|
512
|
+
_context.p = 3;
|
|
513
|
+
self.isDocumentOperationPending = false;
|
|
514
|
+
return _context.f(3);
|
|
515
|
+
case 4:
|
|
516
|
+
return _context.a(2);
|
|
517
|
+
}
|
|
518
|
+
}, _callee, null, [[1,, 3, 4]]);
|
|
519
|
+
})));
|
|
520
|
+
this.documentOperationQueue = nextOperation["finally"](function () {
|
|
521
|
+
if (self.documentOperationQueue === nextOperation) {
|
|
522
|
+
self.documentOperationQueue = null;
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
return this.documentOperationQueue;
|
|
526
|
+
},
|
|
527
|
+
uploadFiles: function uploadFiles(files) {
|
|
528
|
+
var _this = this;
|
|
529
|
+
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
|
|
530
|
+
var filesToUpload;
|
|
531
|
+
return _regenerator().w(function (_context3) {
|
|
532
|
+
while (1) switch (_context3.n) {
|
|
839
533
|
case 0:
|
|
840
534
|
if (config.uploadDocumentUrl) {
|
|
841
|
-
|
|
535
|
+
_context3.n = 1;
|
|
842
536
|
break;
|
|
843
537
|
}
|
|
844
|
-
return
|
|
538
|
+
return _context3.a(2);
|
|
845
539
|
case 1:
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
_context.n = 2;
|
|
540
|
+
filesToUpload = Array.isArray(files) ? files.slice() : Array.from(files || []);
|
|
541
|
+
if (!(filesToUpload.length === 0)) {
|
|
542
|
+
_context3.n = 2;
|
|
850
543
|
break;
|
|
851
544
|
}
|
|
852
|
-
|
|
853
|
-
return _context.a(2);
|
|
545
|
+
return _context3.a(2);
|
|
854
546
|
case 2:
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
547
|
+
return _context3.a(2, _this.queueDocumentOperation(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
548
|
+
var sessionId, profileId, formData, i, response, errorText, uploadError, result, _t, _t2;
|
|
549
|
+
return _regenerator().w(function (_context2) {
|
|
550
|
+
while (1) switch (_context2.p = _context2.n) {
|
|
551
|
+
case 0:
|
|
552
|
+
sessionId = _this.getSessionId();
|
|
553
|
+
profileId = _this.getProfileId();
|
|
554
|
+
if (sessionId) {
|
|
555
|
+
_context2.n = 4;
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
558
|
+
_context2.p = 1;
|
|
559
|
+
_context2.n = 2;
|
|
560
|
+
return _this.ensureSessionForDocuments(profileId);
|
|
561
|
+
case 2:
|
|
562
|
+
sessionId = _context2.v;
|
|
563
|
+
_context2.n = 4;
|
|
564
|
+
break;
|
|
565
|
+
case 3:
|
|
566
|
+
_context2.p = 3;
|
|
567
|
+
_t = _context2.v;
|
|
568
|
+
console.error('Failed to create a chat session for document upload:', _t);
|
|
569
|
+
_this.uploadErrors = [{
|
|
570
|
+
fileName: '',
|
|
571
|
+
error: 'Could not create a chat session for the upload.'
|
|
572
|
+
}];
|
|
573
|
+
_this.renderDocumentBar();
|
|
574
|
+
return _context2.a(2);
|
|
575
|
+
case 4:
|
|
576
|
+
if (sessionId) {
|
|
577
|
+
_context2.n = 5;
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
console.warn('Cannot upload documents without a session or profile.');
|
|
581
|
+
_this.uploadErrors = [{
|
|
582
|
+
fileName: '',
|
|
583
|
+
error: 'Could not create a chat session for the upload.'
|
|
584
|
+
}];
|
|
585
|
+
_this.renderDocumentBar();
|
|
586
|
+
return _context2.a(2);
|
|
587
|
+
case 5:
|
|
588
|
+
_this.isUploading = true;
|
|
589
|
+
_this.uploadErrors = [];
|
|
590
|
+
_this.renderDocumentBar();
|
|
591
|
+
_context2.p = 6;
|
|
592
|
+
formData = new FormData();
|
|
593
|
+
formData.append('sessionId', sessionId);
|
|
594
|
+
for (i = 0; i < filesToUpload.length; i++) {
|
|
595
|
+
formData.append('files', filesToUpload[i]);
|
|
596
|
+
}
|
|
597
|
+
_context2.n = 7;
|
|
598
|
+
return fetch(config.uploadDocumentUrl, {
|
|
599
|
+
method: 'POST',
|
|
600
|
+
body: formData
|
|
601
|
+
});
|
|
602
|
+
case 7:
|
|
603
|
+
response = _context2.v;
|
|
604
|
+
if (response.ok) {
|
|
605
|
+
_context2.n = 9;
|
|
606
|
+
break;
|
|
607
|
+
}
|
|
608
|
+
_context2.n = 8;
|
|
609
|
+
return response.text();
|
|
610
|
+
case 8:
|
|
611
|
+
errorText = _context2.v;
|
|
612
|
+
uploadError = _this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');
|
|
613
|
+
console.error('Upload failed:', errorText);
|
|
614
|
+
_this.uploadErrors = [{
|
|
615
|
+
fileName: '',
|
|
616
|
+
error: uploadError
|
|
617
|
+
}];
|
|
618
|
+
return _context2.a(2);
|
|
619
|
+
case 9:
|
|
620
|
+
_context2.n = 10;
|
|
621
|
+
return response.json();
|
|
622
|
+
case 10:
|
|
623
|
+
result = _context2.v;
|
|
624
|
+
if (result.sessionId && result.sessionId !== _this.getSessionId()) {
|
|
625
|
+
_this.initializeSession(result.sessionId);
|
|
626
|
+
}
|
|
627
|
+
if (Array.isArray(result.documents)) {
|
|
628
|
+
_this.documents = result.documents;
|
|
629
|
+
} else if (result.uploaded && result.uploaded.length > 0) {
|
|
630
|
+
_this.documents = _this.documents.concat(result.uploaded);
|
|
631
|
+
}
|
|
632
|
+
if (result.failed && result.failed.length > 0) {
|
|
633
|
+
_this.uploadErrors = result.failed;
|
|
634
|
+
}
|
|
635
|
+
_context2.n = 12;
|
|
636
|
+
break;
|
|
637
|
+
case 11:
|
|
638
|
+
_context2.p = 11;
|
|
639
|
+
_t2 = _context2.v;
|
|
640
|
+
console.error('Upload error:', _t2);
|
|
641
|
+
_this.uploadErrors = [{
|
|
642
|
+
fileName: '',
|
|
643
|
+
error: 'Upload failed. Please try again.'
|
|
644
|
+
}];
|
|
645
|
+
if (_this.getSessionId()) {
|
|
646
|
+
_this.reloadCurrentSession();
|
|
647
|
+
}
|
|
648
|
+
case 12:
|
|
649
|
+
_context2.p = 12;
|
|
650
|
+
_this.isUploading = false;
|
|
651
|
+
_this.renderDocumentBar();
|
|
652
|
+
return _context2.f(12);
|
|
653
|
+
case 13:
|
|
654
|
+
return _context2.a(2);
|
|
655
|
+
}
|
|
656
|
+
}, _callee2, null, [[6, 11, 12, 13], [1, 3]]);
|
|
657
|
+
}))));
|
|
924
658
|
}
|
|
925
|
-
},
|
|
659
|
+
}, _callee3);
|
|
926
660
|
}))();
|
|
927
661
|
},
|
|
928
662
|
removeDocument: function removeDocument(doc) {
|
|
929
|
-
var
|
|
930
|
-
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
while (1) switch (_context2.p = _context2.n) {
|
|
663
|
+
var _this2 = this;
|
|
664
|
+
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
|
|
665
|
+
return _regenerator().w(function (_context5) {
|
|
666
|
+
while (1) switch (_context5.n) {
|
|
934
667
|
case 0:
|
|
935
668
|
if (config.removeDocumentUrl) {
|
|
936
|
-
|
|
669
|
+
_context5.n = 1;
|
|
937
670
|
break;
|
|
938
671
|
}
|
|
939
|
-
return
|
|
672
|
+
return _context5.a(2);
|
|
940
673
|
case 1:
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
674
|
+
return _context5.a(2, _this2.queueDocumentOperation(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
675
|
+
var sessionId, response, result, idx, errorText, removeError, _t3;
|
|
676
|
+
return _regenerator().w(function (_context4) {
|
|
677
|
+
while (1) switch (_context4.p = _context4.n) {
|
|
678
|
+
case 0:
|
|
679
|
+
_context4.p = 0;
|
|
680
|
+
sessionId = _this2.getSessionId();
|
|
681
|
+
_context4.n = 1;
|
|
682
|
+
return fetch(config.removeDocumentUrl, {
|
|
683
|
+
method: 'POST',
|
|
684
|
+
headers: {
|
|
685
|
+
'Content-Type': 'application/json'
|
|
686
|
+
},
|
|
687
|
+
body: JSON.stringify({
|
|
688
|
+
itemId: sessionId,
|
|
689
|
+
documentId: doc.documentId
|
|
690
|
+
})
|
|
691
|
+
});
|
|
692
|
+
case 1:
|
|
693
|
+
response = _context4.v;
|
|
694
|
+
if (!response.ok) {
|
|
695
|
+
_context4.n = 3;
|
|
696
|
+
break;
|
|
697
|
+
}
|
|
698
|
+
_context4.n = 2;
|
|
699
|
+
return response.json();
|
|
700
|
+
case 2:
|
|
701
|
+
result = _context4.v;
|
|
702
|
+
if (Array.isArray(result.documents)) {
|
|
703
|
+
_this2.documents = result.documents;
|
|
704
|
+
} else {
|
|
705
|
+
idx = _this2.documents.indexOf(doc);
|
|
706
|
+
if (idx > -1) {
|
|
707
|
+
_this2.documents.splice(idx, 1);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
_context4.n = 5;
|
|
711
|
+
break;
|
|
712
|
+
case 3:
|
|
713
|
+
_context4.n = 4;
|
|
714
|
+
return response.text();
|
|
715
|
+
case 4:
|
|
716
|
+
errorText = _context4.v;
|
|
717
|
+
removeError = _this2.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');
|
|
718
|
+
console.error('Failed to remove document:', response.status, errorText);
|
|
719
|
+
_this2.uploadErrors = [{
|
|
720
|
+
fileName: doc.fileName || '',
|
|
721
|
+
error: removeError
|
|
722
|
+
}];
|
|
723
|
+
if (sessionId) {
|
|
724
|
+
_this2.reloadCurrentSession();
|
|
725
|
+
}
|
|
726
|
+
_this2.renderDocumentBar();
|
|
727
|
+
case 5:
|
|
728
|
+
_context4.n = 7;
|
|
729
|
+
break;
|
|
730
|
+
case 6:
|
|
731
|
+
_context4.p = 6;
|
|
732
|
+
_t3 = _context4.v;
|
|
733
|
+
console.error('Remove document error:', _t3);
|
|
734
|
+
_this2.uploadErrors = [{
|
|
735
|
+
fileName: doc.fileName || '',
|
|
736
|
+
error: 'Failed to remove document. Please try again.'
|
|
737
|
+
}];
|
|
738
|
+
if (_this2.getSessionId()) {
|
|
739
|
+
_this2.reloadCurrentSession();
|
|
740
|
+
}
|
|
741
|
+
_this2.renderDocumentBar();
|
|
742
|
+
case 7:
|
|
743
|
+
return _context4.a(2);
|
|
744
|
+
}
|
|
745
|
+
}, _callee4, null, [[0, 6]]);
|
|
746
|
+
}))));
|
|
990
747
|
}
|
|
991
|
-
},
|
|
748
|
+
}, _callee5);
|
|
992
749
|
}))();
|
|
993
750
|
},
|
|
994
751
|
formatFileSize: function formatFileSize(bytes) {
|
|
@@ -1012,7 +769,7 @@ window.openAIChatManager = function () {
|
|
|
1012
769
|
html += '<span class="badge bg-secondary bg-opacity-25 text-dark d-inline-flex align-items-center gap-1 px-2 py-1" style="font-size: 0.8rem;" title="' + this.escapeHtml(doc.fileName || '') + '">';
|
|
1013
770
|
html += '<span class="fa-solid fa-file-lines" style="font-size: 0.7rem;"></span> ';
|
|
1014
771
|
html += this.escapeHtml(name);
|
|
1015
|
-
html += ' <button type="button" class="btn-close btn-close-sm ms-1" style="font-size: 0.5rem;" data-doc-index="' + i + '" aria-label="Remove"></button>';
|
|
772
|
+
html += ' <button type="button" class="btn-close btn-close-sm ms-1" style="font-size: 0.5rem;" data-doc-index="' + i + '" aria-label="Remove"' + (this.isDocumentOperationPending ? ' disabled' : '') + '></button>';
|
|
1016
773
|
html += '</span>';
|
|
1017
774
|
}
|
|
1018
775
|
for (var m = 0; m < this.uploadErrors.length; m++) {
|
|
@@ -1031,7 +788,7 @@ window.openAIChatManager = function () {
|
|
|
1031
788
|
html += '<span class="spinner-border spinner-border-sm" style="width: 0.7rem; height: 0.7rem;"></span> Uploading...';
|
|
1032
789
|
html += '</span>';
|
|
1033
790
|
}
|
|
1034
|
-
html += '<button type="button" class="btn btn-sm btn-outline-secondary rounded-pill ai-chat-doc-add-btn d-inline-flex align-items-center gap-1" style="font-size: 0.75rem; padding: 0.15rem 0.5rem;" title="Attach documents">';
|
|
791
|
+
html += '<button type="button" class="btn btn-sm btn-outline-secondary rounded-pill ai-chat-doc-add-btn d-inline-flex align-items-center gap-1" style="font-size: 0.75rem; padding: 0.15rem 0.5rem;" title="Attach documents"' + (this.isDocumentOperationPending ? ' disabled' : '') + '>';
|
|
1035
792
|
html += '<span class="fa-solid fa-paperclip"></span>';
|
|
1036
793
|
if (this.documents.length === 0 && !this.isUploading) {
|
|
1037
794
|
html += ' <span>Attach files</span>';
|
|
@@ -1054,6 +811,9 @@ window.openAIChatManager = function () {
|
|
|
1054
811
|
return function (e) {
|
|
1055
812
|
e.preventDefault();
|
|
1056
813
|
e.stopPropagation();
|
|
814
|
+
if (self.isDocumentOperationPending) {
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
1057
817
|
var docToRemove = self.documents[idx];
|
|
1058
818
|
if (docToRemove) self.removeDocument(docToRemove);
|
|
1059
819
|
};
|
|
@@ -1078,6 +838,9 @@ window.openAIChatManager = function () {
|
|
|
1078
838
|
if (addBtn) {
|
|
1079
839
|
addBtn.addEventListener('click', function (e) {
|
|
1080
840
|
e.preventDefault();
|
|
841
|
+
if (self.isDocumentOperationPending) {
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
1081
844
|
self.triggerFileInput();
|
|
1082
845
|
});
|
|
1083
846
|
}
|
|
@@ -1154,139 +917,135 @@ window.openAIChatManager = function () {
|
|
|
1154
917
|
return !!message && message.isStreaming && index === this.lastAssistantIndex && !(appearance && appearance.disableStreamingAnimation);
|
|
1155
918
|
},
|
|
1156
919
|
startConnection: function startConnection() {
|
|
1157
|
-
var
|
|
1158
|
-
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
1159
|
-
var
|
|
1160
|
-
return _regenerator().w(function (
|
|
1161
|
-
while (1) switch (
|
|
920
|
+
var _this3 = this;
|
|
921
|
+
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
|
|
922
|
+
var _t4;
|
|
923
|
+
return _regenerator().w(function (_context6) {
|
|
924
|
+
while (1) switch (_context6.p = _context6.n) {
|
|
1162
925
|
case 0:
|
|
1163
|
-
|
|
926
|
+
_this3.connection = new signalR.HubConnectionBuilder().withUrl(config.signalRHubUrl).withAutomaticReconnect().build();
|
|
1164
927
|
|
|
1165
928
|
// Allow long-running operations (e.g., multi-step MCP tool calls)
|
|
1166
929
|
// without the client disconnecting prematurely.
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
930
|
+
_this3.connection.serverTimeoutInMilliseconds = 600000;
|
|
931
|
+
_this3.connection.keepAliveIntervalInMilliseconds = 15000;
|
|
932
|
+
_this3.connection.on("LoadSession", function (data) {
|
|
1170
933
|
var _data$messages;
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
934
|
+
_this3.initializeSession(data.sessionId, true);
|
|
935
|
+
_this3.messages = [];
|
|
936
|
+
_this3.documents = data.documents || [];
|
|
937
|
+
_this3.uploadErrors = [];
|
|
1174
938
|
((_data$messages = data.messages) !== null && _data$messages !== void 0 ? _data$messages : []).forEach(function (msg) {
|
|
1175
|
-
|
|
1176
|
-
|
|
939
|
+
_this3.addMessage(msg);
|
|
940
|
+
_this3.$nextTick(function () {
|
|
1177
941
|
renderChartsInMessage(msg);
|
|
1178
942
|
});
|
|
1179
943
|
});
|
|
1180
944
|
|
|
1181
945
|
// Update feedback icons in the DOM after all messages have rendered.
|
|
1182
|
-
|
|
1183
|
-
|
|
946
|
+
_this3.$nextTick(function () {
|
|
947
|
+
_this3.refreshAllFeedbackIcons();
|
|
1184
948
|
});
|
|
1185
949
|
|
|
1186
950
|
// When the session is new (no messages) and an initial prompt is configured,
|
|
1187
951
|
// automatically send it as the first user message to trigger an AI response.
|
|
1188
|
-
if (
|
|
1189
|
-
|
|
1190
|
-
|
|
952
|
+
if (_this3.messages.length === 0 && config.initialPrompt) {
|
|
953
|
+
_this3.prompt = config.initialPrompt;
|
|
954
|
+
_this3.sendMessage();
|
|
1191
955
|
}
|
|
1192
956
|
});
|
|
1193
|
-
|
|
957
|
+
_this3.connection.on("ReceiveError", function (error) {
|
|
1194
958
|
console.error("SignalR Error: ", error);
|
|
1195
|
-
if (
|
|
1196
|
-
|
|
959
|
+
if (_this3.isRecording) {
|
|
960
|
+
_this3.stopRecording();
|
|
1197
961
|
}
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
// clear the cached session and start fresh with the current profile.
|
|
1201
|
-
if (_this4.widgetIsInitialized && !_this4.isSessionStarted && !_this4._attemptedSessionRecovery) {
|
|
1202
|
-
_this4._attemptedSessionRecovery = true;
|
|
1203
|
-
localStorage.removeItem(_this4.chatWidgetStateSession);
|
|
1204
|
-
_this4.startNewSession();
|
|
962
|
+
if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {
|
|
963
|
+
widgetBehavior.handleReceiveError(_this3, error, config);
|
|
1205
964
|
}
|
|
1206
965
|
});
|
|
1207
|
-
|
|
1208
|
-
var msg =
|
|
966
|
+
_this3.connection.on("MessageRated", function (messageId, userRating) {
|
|
967
|
+
var msg = _this3.messages.find(function (m) {
|
|
1209
968
|
return m.id === messageId;
|
|
1210
969
|
});
|
|
1211
970
|
if (msg) {
|
|
1212
971
|
msg.userRating = userRating;
|
|
1213
972
|
}
|
|
1214
973
|
});
|
|
1215
|
-
|
|
1216
|
-
if (
|
|
974
|
+
_this3.connection.on("ReceiveTranscript", function (sessionId, text, isFinal) {
|
|
975
|
+
if (_this3.isConversationMode) {
|
|
1217
976
|
if (!isFinal && text) {
|
|
1218
|
-
|
|
977
|
+
_this3._conversationPartialTranscript = text;
|
|
1219
978
|
var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
1220
979
|
var html = '<p class="ai-partial-transcript">' + escaped + '</p>';
|
|
1221
980
|
|
|
1222
981
|
// Show partial transcript as a live user message.
|
|
1223
|
-
if (!
|
|
1224
|
-
|
|
1225
|
-
|
|
982
|
+
if (!_this3._conversationPartialMessage) {
|
|
983
|
+
_this3.hidePlaceholder();
|
|
984
|
+
_this3._conversationPartialMessage = {
|
|
1226
985
|
role: 'user',
|
|
1227
986
|
content: text,
|
|
1228
987
|
htmlContent: html,
|
|
1229
988
|
isPartial: true
|
|
1230
989
|
};
|
|
1231
|
-
|
|
990
|
+
_this3.messages.push(_this3._conversationPartialMessage);
|
|
1232
991
|
} else {
|
|
1233
|
-
|
|
1234
|
-
|
|
992
|
+
_this3._conversationPartialMessage.content = text;
|
|
993
|
+
_this3._conversationPartialMessage.htmlContent = html;
|
|
1235
994
|
}
|
|
1236
|
-
|
|
995
|
+
_this3.scrollToBottom();
|
|
1237
996
|
}
|
|
1238
997
|
return;
|
|
1239
998
|
}
|
|
1240
|
-
if (text && !
|
|
1241
|
-
|
|
1242
|
-
if (
|
|
1243
|
-
|
|
1244
|
-
|
|
999
|
+
if (text && !_this3._audioInputSent) {
|
|
1000
|
+
_this3.prompt = _this3.preRecordingPrompt + text;
|
|
1001
|
+
if (_this3.inputElement) {
|
|
1002
|
+
_this3.inputElement.value = _this3.prompt;
|
|
1003
|
+
_this3.inputElement.dispatchEvent(new Event('input'));
|
|
1245
1004
|
}
|
|
1246
1005
|
}
|
|
1247
1006
|
});
|
|
1248
|
-
|
|
1007
|
+
_this3.connection.on("ReceiveConversationUserMessage", function (sessionId, text) {
|
|
1249
1008
|
if (text) {
|
|
1250
|
-
|
|
1009
|
+
_this3.stopAudio();
|
|
1251
1010
|
|
|
1252
1011
|
// If there's an interrupted assistant message still streaming,
|
|
1253
1012
|
// mark it as done to stop the spinner animation.
|
|
1254
|
-
if (
|
|
1255
|
-
var oldMsg =
|
|
1013
|
+
if (_this3._conversationAssistantMessage) {
|
|
1014
|
+
var oldMsg = _this3.messages[_this3._conversationAssistantMessage.index];
|
|
1256
1015
|
if (oldMsg) {
|
|
1257
1016
|
oldMsg.isStreaming = false;
|
|
1258
1017
|
}
|
|
1259
|
-
|
|
1018
|
+
_this3._conversationAssistantMessage = null;
|
|
1260
1019
|
}
|
|
1261
1020
|
|
|
1262
1021
|
// Replace the partial transcript message with the final one.
|
|
1263
|
-
if (
|
|
1022
|
+
if (_this3._conversationPartialMessage) {
|
|
1264
1023
|
var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1024
|
+
_this3._conversationPartialMessage.content = text;
|
|
1025
|
+
_this3._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';
|
|
1026
|
+
_this3._conversationPartialMessage.isPartial = false;
|
|
1027
|
+
_this3._conversationPartialMessage = null;
|
|
1269
1028
|
} else {
|
|
1270
|
-
|
|
1029
|
+
_this3.addMessage({
|
|
1271
1030
|
role: 'user',
|
|
1272
1031
|
content: text
|
|
1273
1032
|
});
|
|
1274
1033
|
}
|
|
1275
|
-
|
|
1034
|
+
_this3.scrollToBottom();
|
|
1276
1035
|
}
|
|
1277
1036
|
});
|
|
1278
|
-
|
|
1279
|
-
if (!
|
|
1280
|
-
|
|
1281
|
-
|
|
1037
|
+
_this3.connection.on("ReceiveConversationAssistantToken", function (sessionId, messageId, token, responseId, appearance) {
|
|
1038
|
+
if (!_this3._conversationAssistantMessage) {
|
|
1039
|
+
_this3.stopAudio();
|
|
1040
|
+
_this3.hideTypingIndicator();
|
|
1282
1041
|
|
|
1283
1042
|
// Ensure no stale streaming indicators remain from prior messages.
|
|
1284
|
-
for (var j = 0; j <
|
|
1285
|
-
if (
|
|
1286
|
-
|
|
1043
|
+
for (var j = 0; j < _this3.messages.length; j++) {
|
|
1044
|
+
if (_this3.messages[j].isStreaming) {
|
|
1045
|
+
_this3.messages[j].isStreaming = false;
|
|
1287
1046
|
}
|
|
1288
1047
|
}
|
|
1289
|
-
var msgIndex =
|
|
1048
|
+
var msgIndex = _this3.messages.length;
|
|
1290
1049
|
var newMessage = {
|
|
1291
1050
|
id: messageId,
|
|
1292
1051
|
role: "assistant",
|
|
@@ -1294,96 +1053,96 @@ window.openAIChatManager = function () {
|
|
|
1294
1053
|
htmlContent: "",
|
|
1295
1054
|
isStreaming: true,
|
|
1296
1055
|
userRating: null,
|
|
1297
|
-
appearance:
|
|
1056
|
+
appearance: _this3.normalizeAssistantAppearance(appearance)
|
|
1298
1057
|
};
|
|
1299
|
-
|
|
1300
|
-
|
|
1058
|
+
_this3.messages.push(newMessage);
|
|
1059
|
+
_this3._conversationAssistantMessage = {
|
|
1301
1060
|
index: msgIndex,
|
|
1302
1061
|
content: ''
|
|
1303
1062
|
};
|
|
1304
1063
|
}
|
|
1305
|
-
|
|
1306
|
-
var msg =
|
|
1064
|
+
_this3._conversationAssistantMessage.content += token;
|
|
1065
|
+
var msg = _this3.messages[_this3._conversationAssistantMessage.index];
|
|
1307
1066
|
if (msg) {
|
|
1308
1067
|
if (!msg.appearance) {
|
|
1309
|
-
msg.appearance =
|
|
1068
|
+
msg.appearance = _this3.normalizeAssistantAppearance(appearance);
|
|
1310
1069
|
}
|
|
1311
|
-
msg.content =
|
|
1070
|
+
msg.content = _this3._conversationAssistantMessage.content;
|
|
1312
1071
|
msg.htmlContent = parseMarkdownContent(msg.content, msg);
|
|
1313
|
-
|
|
1072
|
+
_this3.$nextTick(function () {
|
|
1314
1073
|
renderChartsInMessage(msg);
|
|
1315
|
-
|
|
1074
|
+
_this3.scrollToBottom();
|
|
1316
1075
|
});
|
|
1317
1076
|
}
|
|
1318
1077
|
});
|
|
1319
|
-
|
|
1320
|
-
if (
|
|
1321
|
-
var msg =
|
|
1078
|
+
_this3.connection.on("ReceiveConversationAssistantComplete", function (sessionId, messageId) {
|
|
1079
|
+
if (_this3._conversationAssistantMessage) {
|
|
1080
|
+
var msg = _this3.messages[_this3._conversationAssistantMessage.index];
|
|
1322
1081
|
if (msg) {
|
|
1323
1082
|
msg.isStreaming = false;
|
|
1324
1083
|
}
|
|
1325
|
-
|
|
1084
|
+
_this3._conversationAssistantMessage = null;
|
|
1326
1085
|
}
|
|
1327
1086
|
});
|
|
1328
|
-
|
|
1087
|
+
_this3.connection.on("ReceiveAudioChunk", function (sessionId, base64Audio, contentType) {
|
|
1329
1088
|
if (base64Audio) {
|
|
1330
1089
|
var binaryString = atob(base64Audio);
|
|
1331
1090
|
var bytes = new Uint8Array(binaryString.length);
|
|
1332
1091
|
for (var i = 0; i < binaryString.length; i++) {
|
|
1333
1092
|
bytes[i] = binaryString.charCodeAt(i);
|
|
1334
1093
|
}
|
|
1335
|
-
|
|
1094
|
+
_this3.audioChunks.push(bytes);
|
|
1336
1095
|
}
|
|
1337
1096
|
});
|
|
1338
|
-
|
|
1339
|
-
|
|
1097
|
+
_this3.connection.on("ReceiveAudioComplete", function (sessionId) {
|
|
1098
|
+
_this3.playCollectedAudio();
|
|
1340
1099
|
});
|
|
1341
|
-
|
|
1342
|
-
|
|
1100
|
+
_this3.connection.on("ReceiveNotification", function (notification) {
|
|
1101
|
+
_this3.receiveNotification(notification);
|
|
1343
1102
|
});
|
|
1344
|
-
|
|
1345
|
-
|
|
1103
|
+
_this3.connection.on("UpdateNotification", function (notification) {
|
|
1104
|
+
_this3.updateNotification(notification);
|
|
1346
1105
|
});
|
|
1347
|
-
|
|
1348
|
-
|
|
1106
|
+
_this3.connection.on("RemoveNotification", function (notificationType) {
|
|
1107
|
+
_this3.removeNotification(notificationType);
|
|
1349
1108
|
});
|
|
1350
|
-
|
|
1109
|
+
_this3.connection.onreconnecting(function () {
|
|
1351
1110
|
console.warn("SignalR: reconnecting...");
|
|
1352
1111
|
});
|
|
1353
|
-
|
|
1112
|
+
_this3.connection.onreconnected(function () {
|
|
1354
1113
|
console.info("SignalR: reconnected.");
|
|
1355
|
-
if (
|
|
1356
|
-
|
|
1114
|
+
if (_this3.isSessionStarted) {
|
|
1115
|
+
_this3.reloadCurrentSession();
|
|
1357
1116
|
} else if (config.autoCreateSession) {
|
|
1358
|
-
|
|
1117
|
+
_this3.startNewSession();
|
|
1359
1118
|
}
|
|
1360
1119
|
});
|
|
1361
|
-
|
|
1362
|
-
if (
|
|
1120
|
+
_this3.connection.onclose(function (error) {
|
|
1121
|
+
if (_this3.isNavigatingAway) {
|
|
1363
1122
|
return;
|
|
1364
1123
|
}
|
|
1365
1124
|
if (error) {
|
|
1366
1125
|
console.warn("SignalR connection closed with error:", error.message || error);
|
|
1367
1126
|
}
|
|
1368
1127
|
});
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
return
|
|
1128
|
+
_context6.p = 1;
|
|
1129
|
+
_context6.n = 2;
|
|
1130
|
+
return _this3.connection.start();
|
|
1372
1131
|
case 2:
|
|
1373
|
-
|
|
1132
|
+
_context6.n = 4;
|
|
1374
1133
|
break;
|
|
1375
1134
|
case 3:
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
console.error("SignalR Connection Error: ",
|
|
1135
|
+
_context6.p = 3;
|
|
1136
|
+
_t4 = _context6.v;
|
|
1137
|
+
console.error("SignalR Connection Error: ", _t4);
|
|
1379
1138
|
case 4:
|
|
1380
|
-
return
|
|
1139
|
+
return _context6.a(2);
|
|
1381
1140
|
}
|
|
1382
|
-
},
|
|
1141
|
+
}, _callee6, null, [[1, 3]]);
|
|
1383
1142
|
}))();
|
|
1384
1143
|
},
|
|
1385
1144
|
addMessageInternal: function addMessageInternal(message) {
|
|
1386
|
-
var
|
|
1145
|
+
var _this4 = this;
|
|
1387
1146
|
if (message.role === 'assistant') {
|
|
1388
1147
|
message.appearance = this.normalizeAssistantAppearance(message.appearance);
|
|
1389
1148
|
}
|
|
@@ -1397,7 +1156,7 @@ window.openAIChatManager = function () {
|
|
|
1397
1156
|
}));
|
|
1398
1157
|
this.messages.push(message);
|
|
1399
1158
|
this.$nextTick(function () {
|
|
1400
|
-
|
|
1159
|
+
_this4.fireEvent(new CustomEvent("addedOpenAIPromotMessage", {
|
|
1401
1160
|
detail: {
|
|
1402
1161
|
message: message
|
|
1403
1162
|
}
|
|
@@ -1405,7 +1164,7 @@ window.openAIChatManager = function () {
|
|
|
1405
1164
|
});
|
|
1406
1165
|
},
|
|
1407
1166
|
addMessage: function addMessage(message) {
|
|
1408
|
-
var
|
|
1167
|
+
var _this5 = this;
|
|
1409
1168
|
// Ensure userRating is always defined for Vue reactivity.
|
|
1410
1169
|
if (message.userRating === undefined) {
|
|
1411
1170
|
message.userRating = null;
|
|
@@ -1415,18 +1174,18 @@ window.openAIChatManager = function () {
|
|
|
1415
1174
|
message.references = normalizeReferences(message.references);
|
|
1416
1175
|
if (message.references && _typeof(message.references) === "object" && Object.keys(message.references).length) {
|
|
1417
1176
|
// Only include references that were actually cited in the response.
|
|
1418
|
-
var citedRefs = Object.entries(message.references).filter(function (
|
|
1419
|
-
var
|
|
1420
|
-
key =
|
|
1177
|
+
var citedRefs = Object.entries(message.references).filter(function (_ref7) {
|
|
1178
|
+
var _ref8 = _slicedToArray(_ref7, 1),
|
|
1179
|
+
key = _ref8[0];
|
|
1421
1180
|
return processedContent.includes(key);
|
|
1422
1181
|
});
|
|
1423
1182
|
if (citedRefs.length) {
|
|
1424
1183
|
// Sort by original index so display indices follow a natural order.
|
|
1425
|
-
citedRefs.sort(function (
|
|
1426
|
-
var
|
|
1427
|
-
a =
|
|
1428
|
-
var
|
|
1429
|
-
b =
|
|
1184
|
+
citedRefs.sort(function (_ref9, _ref0) {
|
|
1185
|
+
var _ref1 = _slicedToArray(_ref9, 2),
|
|
1186
|
+
a = _ref1[1];
|
|
1187
|
+
var _ref10 = _slicedToArray(_ref0, 2),
|
|
1188
|
+
b = _ref10[1];
|
|
1430
1189
|
return a.index - b.index;
|
|
1431
1190
|
});
|
|
1432
1191
|
|
|
@@ -1493,17 +1252,17 @@ window.openAIChatManager = function () {
|
|
|
1493
1252
|
this.$nextTick(function () {
|
|
1494
1253
|
// Render any pending charts once the DOM is updated
|
|
1495
1254
|
renderChartsInMessage(message);
|
|
1496
|
-
|
|
1255
|
+
_this5.scrollToBottom();
|
|
1497
1256
|
});
|
|
1498
1257
|
},
|
|
1499
1258
|
addMessages: function addMessages(messages) {
|
|
1500
|
-
var
|
|
1259
|
+
var _this6 = this;
|
|
1501
1260
|
for (var i = 0; i < messages.length; i++) {
|
|
1502
1261
|
this.addMessageInternal(messages[i]);
|
|
1503
1262
|
}
|
|
1504
1263
|
this.hidePlaceholder();
|
|
1505
1264
|
this.$nextTick(function () {
|
|
1506
|
-
|
|
1265
|
+
_this6.scrollToBottom();
|
|
1507
1266
|
});
|
|
1508
1267
|
},
|
|
1509
1268
|
hidePlaceholder: function hidePlaceholder() {
|
|
@@ -1580,7 +1339,7 @@ window.openAIChatManager = function () {
|
|
|
1580
1339
|
this.prompt = '';
|
|
1581
1340
|
},
|
|
1582
1341
|
startRecording: function startRecording() {
|
|
1583
|
-
var
|
|
1342
|
+
var _this7 = this;
|
|
1584
1343
|
if (this.isRecording || !this.connection) {
|
|
1585
1344
|
return;
|
|
1586
1345
|
}
|
|
@@ -1592,27 +1351,27 @@ window.openAIChatManager = function () {
|
|
|
1592
1351
|
}
|
|
1593
1352
|
}).then(function (stream) {
|
|
1594
1353
|
var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus') ? 'audio/ogg;codecs=opus' : MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
|
|
1595
|
-
|
|
1354
|
+
_this7.mediaRecorder = new MediaRecorder(stream, {
|
|
1596
1355
|
mimeType: mimeType,
|
|
1597
1356
|
audioBitsPerSecond: 128000
|
|
1598
1357
|
});
|
|
1599
|
-
|
|
1600
|
-
|
|
1358
|
+
_this7.preRecordingPrompt = _this7.prompt;
|
|
1359
|
+
_this7._audioInputSent = false;
|
|
1601
1360
|
var subject = new signalR.Subject();
|
|
1602
|
-
var profileId =
|
|
1603
|
-
var sessionId =
|
|
1361
|
+
var profileId = _this7.getProfileId();
|
|
1362
|
+
var sessionId = _this7.getSessionId() || '';
|
|
1604
1363
|
var pendingChunk = Promise.resolve();
|
|
1605
|
-
|
|
1364
|
+
_this7.mediaRecorder.addEventListener('dataavailable', function (e) {
|
|
1606
1365
|
if (e.data && e.data.size > 0) {
|
|
1607
|
-
pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
1366
|
+
pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7() {
|
|
1608
1367
|
var data, uint8Array, binaryString, base64;
|
|
1609
|
-
return _regenerator().w(function (
|
|
1610
|
-
while (1) switch (
|
|
1368
|
+
return _regenerator().w(function (_context7) {
|
|
1369
|
+
while (1) switch (_context7.n) {
|
|
1611
1370
|
case 0:
|
|
1612
|
-
|
|
1371
|
+
_context7.n = 1;
|
|
1613
1372
|
return e.data.arrayBuffer();
|
|
1614
1373
|
case 1:
|
|
1615
|
-
data =
|
|
1374
|
+
data = _context7.v;
|
|
1616
1375
|
uint8Array = new Uint8Array(data);
|
|
1617
1376
|
binaryString = uint8Array.reduce(function (str, _byte) {
|
|
1618
1377
|
return str + String.fromCharCode(_byte);
|
|
@@ -1620,13 +1379,13 @@ window.openAIChatManager = function () {
|
|
|
1620
1379
|
base64 = btoa(binaryString);
|
|
1621
1380
|
subject.next(base64);
|
|
1622
1381
|
case 2:
|
|
1623
|
-
return
|
|
1382
|
+
return _context7.a(2);
|
|
1624
1383
|
}
|
|
1625
|
-
},
|
|
1384
|
+
}, _callee7);
|
|
1626
1385
|
})));
|
|
1627
1386
|
}
|
|
1628
1387
|
});
|
|
1629
|
-
|
|
1388
|
+
_this7.mediaRecorder.addEventListener('stop', function () {
|
|
1630
1389
|
stream.getTracks().forEach(function (track) {
|
|
1631
1390
|
return track.stop();
|
|
1632
1391
|
});
|
|
@@ -1635,10 +1394,10 @@ window.openAIChatManager = function () {
|
|
|
1635
1394
|
});
|
|
1636
1395
|
});
|
|
1637
1396
|
var language = navigator.language || document.documentElement.lang || 'en-US';
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1397
|
+
_this7.connection.send("SendAudioStream", profileId, sessionId, subject, mimeType, language);
|
|
1398
|
+
_this7.mediaRecorder.start(250);
|
|
1399
|
+
_this7.isRecording = true;
|
|
1400
|
+
_this7.updateMicButton();
|
|
1642
1401
|
})["catch"](function (err) {
|
|
1643
1402
|
console.error('Microphone access denied:', err);
|
|
1644
1403
|
});
|
|
@@ -1671,7 +1430,7 @@ window.openAIChatManager = function () {
|
|
|
1671
1430
|
}
|
|
1672
1431
|
},
|
|
1673
1432
|
streamMessage: function streamMessage(profileId, trimmedPrompt, sessionProfileId) {
|
|
1674
|
-
var
|
|
1433
|
+
var _this8 = this;
|
|
1675
1434
|
if (this.stream) {
|
|
1676
1435
|
this.stream.dispose();
|
|
1677
1436
|
this.stream = null;
|
|
@@ -1688,14 +1447,14 @@ window.openAIChatManager = function () {
|
|
|
1688
1447
|
var currentSessionId = this.getSessionId();
|
|
1689
1448
|
this.stream = this.connection.stream("SendMessage", profileId, trimmedPrompt, currentSessionId, sessionProfileId).subscribe({
|
|
1690
1449
|
next: function next(chunk) {
|
|
1691
|
-
var message =
|
|
1450
|
+
var message = _this8.messages[messageIndex];
|
|
1692
1451
|
if (!message) {
|
|
1693
1452
|
if (chunk.sessionId && !currentSessionId) {
|
|
1694
|
-
|
|
1453
|
+
_this8.initializeSession(chunk.sessionId);
|
|
1695
1454
|
}
|
|
1696
|
-
|
|
1455
|
+
_this8.hideTypingIndicator();
|
|
1697
1456
|
// Re-assign the index after hiding the typing indicator.
|
|
1698
|
-
messageIndex =
|
|
1457
|
+
messageIndex = _this8.messages.length;
|
|
1699
1458
|
var newMessage = {
|
|
1700
1459
|
id: chunk.messageId,
|
|
1701
1460
|
role: "assistant",
|
|
@@ -1705,7 +1464,7 @@ window.openAIChatManager = function () {
|
|
|
1705
1464
|
isStreaming: true,
|
|
1706
1465
|
userRating: null
|
|
1707
1466
|
};
|
|
1708
|
-
|
|
1467
|
+
_this8.messages.push(newMessage);
|
|
1709
1468
|
message = newMessage;
|
|
1710
1469
|
}
|
|
1711
1470
|
if (chunk.title && (!message.title || message.title !== chunk.title)) {
|
|
@@ -1745,46 +1504,46 @@ window.openAIChatManager = function () {
|
|
|
1745
1504
|
// Update the existing message
|
|
1746
1505
|
message.content = content;
|
|
1747
1506
|
message.htmlContent = parseMarkdownContent(content, message);
|
|
1748
|
-
|
|
1749
|
-
|
|
1507
|
+
_this8.messages[messageIndex] = message;
|
|
1508
|
+
_this8.$nextTick(function () {
|
|
1750
1509
|
renderChartsInMessage(message);
|
|
1751
|
-
|
|
1510
|
+
_this8.scrollToBottom();
|
|
1752
1511
|
});
|
|
1753
1512
|
},
|
|
1754
1513
|
complete: function complete() {
|
|
1755
|
-
var
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
var msg =
|
|
1514
|
+
var _this8$stream;
|
|
1515
|
+
_this8.processReferences(references, messageIndex);
|
|
1516
|
+
_this8.streamingFinished();
|
|
1517
|
+
var msg = _this8.messages[messageIndex];
|
|
1759
1518
|
if (msg) {
|
|
1760
1519
|
msg.isStreaming = false;
|
|
1761
1520
|
}
|
|
1762
1521
|
if (!msg || !msg.content) {
|
|
1763
1522
|
// No content received at all.
|
|
1764
|
-
|
|
1523
|
+
_this8.hideTypingIndicator();
|
|
1765
1524
|
}
|
|
1766
1525
|
|
|
1767
1526
|
// Trigger text-to-speech only in conversation mode.
|
|
1768
|
-
if (
|
|
1769
|
-
|
|
1527
|
+
if (_this8.isConversationMode && _this8.textToSpeechEnabled && msg && msg.content) {
|
|
1528
|
+
_this8.synthesizeSpeech(msg.content);
|
|
1770
1529
|
}
|
|
1771
|
-
(
|
|
1772
|
-
|
|
1530
|
+
(_this8$stream = _this8.stream) === null || _this8$stream === void 0 || _this8$stream.dispose();
|
|
1531
|
+
_this8.stream = null;
|
|
1773
1532
|
},
|
|
1774
1533
|
error: function error(err) {
|
|
1775
|
-
var
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
var msg =
|
|
1534
|
+
var _this8$stream2;
|
|
1535
|
+
_this8.processReferences(references, messageIndex);
|
|
1536
|
+
_this8.streamingFinished();
|
|
1537
|
+
var msg = _this8.messages[messageIndex];
|
|
1779
1538
|
if (msg) {
|
|
1780
1539
|
msg.isStreaming = false;
|
|
1781
1540
|
}
|
|
1782
|
-
|
|
1783
|
-
if (!
|
|
1784
|
-
|
|
1541
|
+
_this8.hideTypingIndicator();
|
|
1542
|
+
if (!_this8.isNavigatingAway) {
|
|
1543
|
+
_this8.addMessage(_this8.getServiceDownMessage());
|
|
1785
1544
|
}
|
|
1786
|
-
(
|
|
1787
|
-
|
|
1545
|
+
(_this8$stream2 = _this8.stream) === null || _this8$stream2 === void 0 || _this8$stream2.dispose();
|
|
1546
|
+
_this8.stream = null;
|
|
1788
1547
|
console.error("Stream error:", err);
|
|
1789
1548
|
}
|
|
1790
1549
|
});
|
|
@@ -1798,7 +1557,7 @@ window.openAIChatManager = function () {
|
|
|
1798
1557
|
return newMessage;
|
|
1799
1558
|
},
|
|
1800
1559
|
processReferences: function processReferences(references, messageIndex) {
|
|
1801
|
-
var
|
|
1560
|
+
var _this9 = this;
|
|
1802
1561
|
references = normalizeReferences(references);
|
|
1803
1562
|
if (Object.keys(references).length) {
|
|
1804
1563
|
var message = this.messages[messageIndex];
|
|
@@ -1806,10 +1565,10 @@ window.openAIChatManager = function () {
|
|
|
1806
1565
|
|
|
1807
1566
|
// Only include references that were actually cited in the response.
|
|
1808
1567
|
// Check both raw [doc:N] markers and already-rendered <sup> tags from streaming.
|
|
1809
|
-
var citedRefs = Object.entries(references).filter(function (
|
|
1810
|
-
var
|
|
1811
|
-
key =
|
|
1812
|
-
value =
|
|
1568
|
+
var citedRefs = Object.entries(references).filter(function (_ref12) {
|
|
1569
|
+
var _ref13 = _slicedToArray(_ref12, 2),
|
|
1570
|
+
key = _ref13[0],
|
|
1571
|
+
value = _ref13[1];
|
|
1813
1572
|
return content.includes(key) || content.includes("<sup><strong>".concat(value.index, "</strong></sup>"));
|
|
1814
1573
|
});
|
|
1815
1574
|
if (!citedRefs.length) {
|
|
@@ -1817,11 +1576,11 @@ window.openAIChatManager = function () {
|
|
|
1817
1576
|
}
|
|
1818
1577
|
|
|
1819
1578
|
// Sort by original index so display indices follow a natural order.
|
|
1820
|
-
citedRefs.sort(function (
|
|
1821
|
-
var
|
|
1822
|
-
a =
|
|
1823
|
-
var
|
|
1824
|
-
b =
|
|
1579
|
+
citedRefs.sort(function (_ref14, _ref15) {
|
|
1580
|
+
var _ref16 = _slicedToArray(_ref14, 2),
|
|
1581
|
+
a = _ref16[1];
|
|
1582
|
+
var _ref17 = _slicedToArray(_ref15, 2),
|
|
1583
|
+
b = _ref17[1];
|
|
1825
1584
|
return a.index - b.index;
|
|
1826
1585
|
});
|
|
1827
1586
|
|
|
@@ -1883,7 +1642,7 @@ window.openAIChatManager = function () {
|
|
|
1883
1642
|
this.messages[messageIndex] = message;
|
|
1884
1643
|
this.$nextTick(function () {
|
|
1885
1644
|
renderChartsInMessage(message);
|
|
1886
|
-
|
|
1645
|
+
_this9.scrollToBottom();
|
|
1887
1646
|
});
|
|
1888
1647
|
}
|
|
1889
1648
|
},
|
|
@@ -1934,14 +1693,14 @@ window.openAIChatManager = function () {
|
|
|
1934
1693
|
this.stopAudio(false);
|
|
1935
1694
|
},
|
|
1936
1695
|
updateTtsPlaybackButtons: function updateTtsPlaybackButtons() {
|
|
1937
|
-
var
|
|
1696
|
+
var _this0 = this;
|
|
1938
1697
|
if (!this.chatContainer) {
|
|
1939
1698
|
return;
|
|
1940
1699
|
}
|
|
1941
1700
|
var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');
|
|
1942
1701
|
buttons.forEach(function (button) {
|
|
1943
1702
|
var buttonIndex = Number(button.getAttribute('data-tts-message-index'));
|
|
1944
|
-
var isPlaying = buttonIndex ===
|
|
1703
|
+
var isPlaying = buttonIndex === _this0.ttsPlayingMessageIndex;
|
|
1945
1704
|
var iconHtml = isPlaying ? '<span class="fa-solid fa-circle-pause"></span>' : '<span class="fa-solid fa-circle-play"></span>';
|
|
1946
1705
|
button.classList.toggle('tts-playing', isPlaying);
|
|
1947
1706
|
button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');
|
|
@@ -1951,7 +1710,7 @@ window.openAIChatManager = function () {
|
|
|
1951
1710
|
});
|
|
1952
1711
|
},
|
|
1953
1712
|
synthesizeSpeech: function synthesizeSpeech(text, cacheIndex) {
|
|
1954
|
-
var
|
|
1713
|
+
var _this1 = this;
|
|
1955
1714
|
if (!this.textToSpeechEnabled || !text || !this.connection) {
|
|
1956
1715
|
return;
|
|
1957
1716
|
}
|
|
@@ -1960,16 +1719,16 @@ window.openAIChatManager = function () {
|
|
|
1960
1719
|
this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;
|
|
1961
1720
|
this.connection.invoke("SynthesizeSpeech", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)["catch"](function (err) {
|
|
1962
1721
|
console.error("TTS synthesis error:", err);
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
return
|
|
1722
|
+
_this1.isPlayingAudio = false;
|
|
1723
|
+
_this1.ttsPlayingMessageIndex = -1;
|
|
1724
|
+
_this1._ttsCacheIndex = -1;
|
|
1725
|
+
_this1.$nextTick(function () {
|
|
1726
|
+
return _this1.updateTtsPlaybackButtons();
|
|
1968
1727
|
});
|
|
1969
1728
|
});
|
|
1970
1729
|
},
|
|
1971
1730
|
toggleMessageTts: function toggleMessageTts(message, index) {
|
|
1972
|
-
var
|
|
1731
|
+
var _this10 = this;
|
|
1973
1732
|
if (this.ttsPlayingMessageIndex === index) {
|
|
1974
1733
|
this.stopAudio();
|
|
1975
1734
|
return;
|
|
@@ -1982,7 +1741,7 @@ window.openAIChatManager = function () {
|
|
|
1982
1741
|
}));
|
|
1983
1742
|
this.ttsPlayingMessageIndex = index;
|
|
1984
1743
|
this.$nextTick(function () {
|
|
1985
|
-
return
|
|
1744
|
+
return _this10.updateTtsPlaybackButtons();
|
|
1986
1745
|
});
|
|
1987
1746
|
if (this.ttsAudioCache[index]) {
|
|
1988
1747
|
this.playAudioBlob(this.ttsAudioCache[index]);
|
|
@@ -1991,13 +1750,13 @@ window.openAIChatManager = function () {
|
|
|
1991
1750
|
this.synthesizeSpeech(message.content, index);
|
|
1992
1751
|
},
|
|
1993
1752
|
playCollectedAudio: function playCollectedAudio() {
|
|
1994
|
-
var
|
|
1753
|
+
var _this11 = this;
|
|
1995
1754
|
if (this.audioChunks.length === 0) {
|
|
1996
1755
|
if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {
|
|
1997
1756
|
this.isPlayingAudio = false;
|
|
1998
1757
|
this.ttsPlayingMessageIndex = -1;
|
|
1999
1758
|
this.$nextTick(function () {
|
|
2000
|
-
return
|
|
1759
|
+
return _this11.updateTtsPlaybackButtons();
|
|
2001
1760
|
});
|
|
2002
1761
|
}
|
|
2003
1762
|
return;
|
|
@@ -2037,39 +1796,39 @@ window.openAIChatManager = function () {
|
|
|
2037
1796
|
this.playAudioBlob(blob);
|
|
2038
1797
|
},
|
|
2039
1798
|
playAudioBlob: function playAudioBlob(blob) {
|
|
2040
|
-
var
|
|
1799
|
+
var _this12 = this;
|
|
2041
1800
|
var url = URL.createObjectURL(blob);
|
|
2042
1801
|
var audio = new Audio(url);
|
|
2043
1802
|
this.currentAudioUrl = url;
|
|
2044
1803
|
this.currentAudioElement = audio;
|
|
2045
1804
|
this.isPlayingAudio = true;
|
|
2046
1805
|
audio.addEventListener('ended', function () {
|
|
2047
|
-
|
|
2048
|
-
|
|
1806
|
+
_this12.currentAudioElement = null;
|
|
1807
|
+
_this12.currentAudioUrl = null;
|
|
2049
1808
|
URL.revokeObjectURL(url);
|
|
2050
|
-
|
|
1809
|
+
_this12.playNextInQueue();
|
|
2051
1810
|
});
|
|
2052
1811
|
audio.addEventListener('error', function () {
|
|
2053
|
-
|
|
2054
|
-
|
|
1812
|
+
_this12.currentAudioElement = null;
|
|
1813
|
+
_this12.currentAudioUrl = null;
|
|
2055
1814
|
URL.revokeObjectURL(url);
|
|
2056
|
-
|
|
1815
|
+
_this12.playNextInQueue();
|
|
2057
1816
|
});
|
|
2058
1817
|
audio.play()["catch"](function (err) {
|
|
2059
1818
|
console.error("Audio playback error:", err);
|
|
2060
|
-
|
|
2061
|
-
|
|
1819
|
+
_this12.currentAudioElement = null;
|
|
1820
|
+
_this12.currentAudioUrl = null;
|
|
2062
1821
|
URL.revokeObjectURL(url);
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
return
|
|
1822
|
+
_this12.audioPlayQueue = [];
|
|
1823
|
+
_this12.isPlayingAudio = false;
|
|
1824
|
+
_this12.ttsPlayingMessageIndex = -1;
|
|
1825
|
+
_this12.$nextTick(function () {
|
|
1826
|
+
return _this12.updateTtsPlaybackButtons();
|
|
2068
1827
|
});
|
|
2069
1828
|
});
|
|
2070
1829
|
},
|
|
2071
1830
|
playNextInQueue: function playNextInQueue() {
|
|
2072
|
-
var
|
|
1831
|
+
var _this13 = this;
|
|
2073
1832
|
if (this.audioPlayQueue.length > 0) {
|
|
2074
1833
|
var nextBlob = this.audioPlayQueue.shift();
|
|
2075
1834
|
this.playAudioBlob(nextBlob);
|
|
@@ -2077,13 +1836,13 @@ window.openAIChatManager = function () {
|
|
|
2077
1836
|
this.isPlayingAudio = false;
|
|
2078
1837
|
this.ttsPlayingMessageIndex = -1;
|
|
2079
1838
|
this.$nextTick(function () {
|
|
2080
|
-
return
|
|
1839
|
+
return _this13.updateTtsPlaybackButtons();
|
|
2081
1840
|
});
|
|
2082
1841
|
this.conversationModeOnAudioEnded();
|
|
2083
1842
|
}
|
|
2084
1843
|
},
|
|
2085
1844
|
stopAudio: function stopAudio() {
|
|
2086
|
-
var
|
|
1845
|
+
var _this14 = this;
|
|
2087
1846
|
if (this.currentAudioElement) {
|
|
2088
1847
|
this.currentAudioElement.pause();
|
|
2089
1848
|
this.currentAudioElement.currentTime = 0;
|
|
@@ -2098,7 +1857,7 @@ window.openAIChatManager = function () {
|
|
|
2098
1857
|
this.isPlayingAudio = false;
|
|
2099
1858
|
this.ttsPlayingMessageIndex = -1;
|
|
2100
1859
|
this.$nextTick(function () {
|
|
2101
|
-
return
|
|
1860
|
+
return _this14.updateTtsPlaybackButtons();
|
|
2102
1861
|
});
|
|
2103
1862
|
},
|
|
2104
1863
|
toggleConversationMode: function toggleConversationMode() {
|
|
@@ -2109,7 +1868,7 @@ window.openAIChatManager = function () {
|
|
|
2109
1868
|
}
|
|
2110
1869
|
},
|
|
2111
1870
|
startConversationMode: function startConversationMode() {
|
|
2112
|
-
var
|
|
1871
|
+
var _this15 = this;
|
|
2113
1872
|
if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {
|
|
2114
1873
|
return;
|
|
2115
1874
|
}
|
|
@@ -2129,12 +1888,12 @@ window.openAIChatManager = function () {
|
|
|
2129
1888
|
}
|
|
2130
1889
|
}).then(function (stream) {
|
|
2131
1890
|
var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus') ? 'audio/ogg;codecs=opus' : MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
|
|
2132
|
-
|
|
1891
|
+
_this15.mediaRecorder = new MediaRecorder(stream, {
|
|
2133
1892
|
mimeType: mimeType,
|
|
2134
1893
|
audioBitsPerSecond: 128000
|
|
2135
1894
|
});
|
|
2136
|
-
|
|
2137
|
-
|
|
1895
|
+
_this15._conversationSubject = new signalR.Subject();
|
|
1896
|
+
_this15._conversationStream = stream;
|
|
2138
1897
|
|
|
2139
1898
|
// Create an AnalyserNode for volume-based interrupt detection.
|
|
2140
1899
|
// During TTS playback, detect when the user speaks above
|
|
@@ -2143,20 +1902,20 @@ window.openAIChatManager = function () {
|
|
|
2143
1902
|
// speaker echo so the STT stream has no gaps.
|
|
2144
1903
|
var AudioCtx = window.AudioContext || window.webkitAudioContext;
|
|
2145
1904
|
if (AudioCtx) {
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
var micSource =
|
|
2150
|
-
micSource.connect(
|
|
1905
|
+
_this15._conversationAudioCtx = new AudioCtx();
|
|
1906
|
+
_this15._conversationAnalyser = _this15._conversationAudioCtx.createAnalyser();
|
|
1907
|
+
_this15._conversationAnalyser.fftSize = 256;
|
|
1908
|
+
var micSource = _this15._conversationAudioCtx.createMediaStreamSource(stream);
|
|
1909
|
+
micSource.connect(_this15._conversationAnalyser);
|
|
2151
1910
|
}
|
|
2152
1911
|
var pendingChunk = Promise.resolve();
|
|
2153
|
-
var analyser =
|
|
1912
|
+
var analyser = _this15._conversationAnalyser;
|
|
2154
1913
|
var interruptVolumeThreshold = 30;
|
|
2155
|
-
|
|
1914
|
+
_this15.mediaRecorder.addEventListener('dataavailable', function (e) {
|
|
2156
1915
|
if (e.data && e.data.size > 0) {
|
|
2157
1916
|
// During TTS playback, check mic volume to detect
|
|
2158
1917
|
// user interruption (speaking above threshold).
|
|
2159
|
-
if (
|
|
1918
|
+
if (_this15.isPlayingAudio && analyser) {
|
|
2160
1919
|
var freqData = new Uint8Array(analyser.frequencyBinCount);
|
|
2161
1920
|
analyser.getByteFrequencyData(freqData);
|
|
2162
1921
|
var sum = 0;
|
|
@@ -2166,61 +1925,61 @@ window.openAIChatManager = function () {
|
|
|
2166
1925
|
var avg = sum / freqData.length;
|
|
2167
1926
|
if (avg >= interruptVolumeThreshold) {
|
|
2168
1927
|
// User is speaking — interrupt TTS playback.
|
|
2169
|
-
|
|
1928
|
+
_this15.stopAudio();
|
|
2170
1929
|
}
|
|
2171
1930
|
}
|
|
2172
1931
|
|
|
2173
1932
|
// Always send audio to STT — browser echo cancellation
|
|
2174
1933
|
// handles speaker echo; continuous audio avoids gaps
|
|
2175
1934
|
// that increase recognition latency.
|
|
2176
|
-
pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
1935
|
+
pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
|
|
2177
1936
|
var data, uint8Array, binaryString, base64;
|
|
2178
|
-
return _regenerator().w(function (
|
|
2179
|
-
while (1) switch (
|
|
1937
|
+
return _regenerator().w(function (_context8) {
|
|
1938
|
+
while (1) switch (_context8.n) {
|
|
2180
1939
|
case 0:
|
|
2181
|
-
|
|
1940
|
+
_context8.n = 1;
|
|
2182
1941
|
return e.data.arrayBuffer();
|
|
2183
1942
|
case 1:
|
|
2184
|
-
data =
|
|
1943
|
+
data = _context8.v;
|
|
2185
1944
|
uint8Array = new Uint8Array(data);
|
|
2186
1945
|
binaryString = uint8Array.reduce(function (str, _byte2) {
|
|
2187
1946
|
return str + String.fromCharCode(_byte2);
|
|
2188
1947
|
}, '');
|
|
2189
1948
|
base64 = btoa(binaryString);
|
|
2190
1949
|
try {
|
|
2191
|
-
|
|
1950
|
+
_this15._conversationSubject.next(base64);
|
|
2192
1951
|
} catch (err) {
|
|
2193
1952
|
// Subject may have been completed already.
|
|
2194
1953
|
}
|
|
2195
1954
|
case 2:
|
|
2196
|
-
return
|
|
1955
|
+
return _context8.a(2);
|
|
2197
1956
|
}
|
|
2198
|
-
},
|
|
1957
|
+
}, _callee8);
|
|
2199
1958
|
})));
|
|
2200
1959
|
}
|
|
2201
1960
|
});
|
|
2202
|
-
|
|
1961
|
+
_this15.mediaRecorder.addEventListener('stop', function () {
|
|
2203
1962
|
stream.getTracks().forEach(function (track) {
|
|
2204
1963
|
return track.stop();
|
|
2205
1964
|
});
|
|
2206
1965
|
pendingChunk.then(function () {
|
|
2207
1966
|
try {
|
|
2208
|
-
|
|
1967
|
+
_this15._conversationSubject.complete();
|
|
2209
1968
|
} catch (err) {
|
|
2210
1969
|
// Already completed.
|
|
2211
1970
|
}
|
|
2212
1971
|
});
|
|
2213
1972
|
});
|
|
2214
|
-
var profileId =
|
|
2215
|
-
var sessionId =
|
|
1973
|
+
var profileId = _this15.getProfileId();
|
|
1974
|
+
var sessionId = _this15.getSessionId() || '';
|
|
2216
1975
|
var language = navigator.language || document.documentElement.lang || 'en-US';
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
1976
|
+
_this15.connection.send("StartConversation", profileId, sessionId, _this15._conversationSubject, mimeType, language);
|
|
1977
|
+
_this15.mediaRecorder.start(250);
|
|
1978
|
+
_this15.isRecording = true;
|
|
2220
1979
|
})["catch"](function (err) {
|
|
2221
1980
|
console.error('Microphone access denied:', err);
|
|
2222
|
-
|
|
2223
|
-
|
|
1981
|
+
_this15.isConversationMode = false;
|
|
1982
|
+
_this15.updateConversationButton();
|
|
2224
1983
|
});
|
|
2225
1984
|
},
|
|
2226
1985
|
stopConversationMode: function stopConversationMode() {
|
|
@@ -2347,7 +2106,7 @@ window.openAIChatManager = function () {
|
|
|
2347
2106
|
return removedCount;
|
|
2348
2107
|
},
|
|
2349
2108
|
receiveNotification: function receiveNotification(notification) {
|
|
2350
|
-
var
|
|
2109
|
+
var _this16 = this;
|
|
2351
2110
|
if (!notification || !notification.type) {
|
|
2352
2111
|
return;
|
|
2353
2112
|
}
|
|
@@ -2362,7 +2121,7 @@ window.openAIChatManager = function () {
|
|
|
2362
2121
|
}
|
|
2363
2122
|
this.scheduleNotificationDismiss(notification);
|
|
2364
2123
|
this.$nextTick(function () {
|
|
2365
|
-
|
|
2124
|
+
_this16.scrollToBottom();
|
|
2366
2125
|
});
|
|
2367
2126
|
},
|
|
2368
2127
|
updateNotification: function updateNotification(notification) {
|
|
@@ -2379,12 +2138,12 @@ window.openAIChatManager = function () {
|
|
|
2379
2138
|
}
|
|
2380
2139
|
},
|
|
2381
2140
|
scheduleNotificationDismiss: function scheduleNotificationDismiss(notification) {
|
|
2382
|
-
var
|
|
2141
|
+
var _this17 = this;
|
|
2383
2142
|
if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {
|
|
2384
2143
|
return;
|
|
2385
2144
|
}
|
|
2386
2145
|
this.notificationDismissTimers[notification.type] = setTimeout(function () {
|
|
2387
|
-
|
|
2146
|
+
_this17.removeNotification(notification.type);
|
|
2388
2147
|
}, notification.autoDismissMs);
|
|
2389
2148
|
},
|
|
2390
2149
|
clearNotificationDismiss: function clearNotificationDismiss(notificationType) {
|
|
@@ -2414,31 +2173,32 @@ window.openAIChatManager = function () {
|
|
|
2414
2173
|
});
|
|
2415
2174
|
},
|
|
2416
2175
|
scrollToBottom: function scrollToBottom() {
|
|
2417
|
-
var
|
|
2176
|
+
var _this18 = this;
|
|
2418
2177
|
if (!this.autoScroll) {
|
|
2419
2178
|
return;
|
|
2420
2179
|
}
|
|
2421
2180
|
setTimeout(function () {
|
|
2422
|
-
|
|
2181
|
+
_this18.chatContainer.scrollTop = _this18.chatContainer.scrollHeight - _this18.chatContainer.clientHeight;
|
|
2423
2182
|
}, 50);
|
|
2424
2183
|
},
|
|
2425
2184
|
handleUserInput: function handleUserInput(event) {
|
|
2426
2185
|
this.prompt = event.target.value;
|
|
2427
2186
|
},
|
|
2428
2187
|
getProfileId: function getProfileId() {
|
|
2429
|
-
return this.inputElement.getAttribute('data-profile-id');
|
|
2188
|
+
return this.inputElement ? this.inputElement.getAttribute('data-profile-id') : null;
|
|
2430
2189
|
},
|
|
2431
2190
|
setSessionId: function setSessionId(sessionId) {
|
|
2191
|
+
if (!this.inputElement) {
|
|
2192
|
+
return;
|
|
2193
|
+
}
|
|
2432
2194
|
this.inputElement.setAttribute('data-session-id', sessionId || '');
|
|
2433
2195
|
},
|
|
2434
2196
|
resetSession: function resetSession() {
|
|
2435
2197
|
this.stopRecording();
|
|
2198
|
+
this.rejectPendingSessionRequest('Session was reset.');
|
|
2436
2199
|
this.setSessionId('');
|
|
2437
2200
|
this.isSessionStarted = false;
|
|
2438
2201
|
this.sessionRating = null;
|
|
2439
|
-
if (this.widgetIsInitialized) {
|
|
2440
|
-
localStorage.removeItem(this.chatWidgetStateSession);
|
|
2441
|
-
}
|
|
2442
2202
|
this.messages = [];
|
|
2443
2203
|
this.documents = [];
|
|
2444
2204
|
if (!config.autoCreateSession) {
|
|
@@ -2447,6 +2207,9 @@ window.openAIChatManager = function () {
|
|
|
2447
2207
|
if (config.autoCreateSession) {
|
|
2448
2208
|
this.startNewSession();
|
|
2449
2209
|
}
|
|
2210
|
+
if (widgetBehavior && typeof widgetBehavior.onSessionReset === 'function') {
|
|
2211
|
+
widgetBehavior.onSessionReset(this, config);
|
|
2212
|
+
}
|
|
2450
2213
|
},
|
|
2451
2214
|
startNewSession: function startNewSession() {
|
|
2452
2215
|
if (!this.applyOrchestratorAvailability()) {
|
|
@@ -2456,16 +2219,94 @@ window.openAIChatManager = function () {
|
|
|
2456
2219
|
if (!profileId || !this.connection) {
|
|
2457
2220
|
return;
|
|
2458
2221
|
}
|
|
2459
|
-
this.
|
|
2222
|
+
this.requestNewSession(profileId)["catch"](function (err) {
|
|
2460
2223
|
return console.error(err);
|
|
2461
2224
|
});
|
|
2462
2225
|
},
|
|
2463
|
-
|
|
2226
|
+
ensureSessionForDocuments: function ensureSessionForDocuments(profileId) {
|
|
2227
|
+
var _this19 = this;
|
|
2228
|
+
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9() {
|
|
2229
|
+
var sessionId;
|
|
2230
|
+
return _regenerator().w(function (_context9) {
|
|
2231
|
+
while (1) switch (_context9.n) {
|
|
2232
|
+
case 0:
|
|
2233
|
+
sessionId = _this19.getSessionId();
|
|
2234
|
+
if (!sessionId) {
|
|
2235
|
+
_context9.n = 1;
|
|
2236
|
+
break;
|
|
2237
|
+
}
|
|
2238
|
+
return _context9.a(2, sessionId);
|
|
2239
|
+
case 1:
|
|
2240
|
+
if (!(!profileId || !_this19.connection)) {
|
|
2241
|
+
_context9.n = 2;
|
|
2242
|
+
break;
|
|
2243
|
+
}
|
|
2244
|
+
return _context9.a(2, null);
|
|
2245
|
+
case 2:
|
|
2246
|
+
_context9.n = 3;
|
|
2247
|
+
return _this19.requestNewSession(profileId);
|
|
2248
|
+
case 3:
|
|
2249
|
+
return _context9.a(2, _context9.v);
|
|
2250
|
+
}
|
|
2251
|
+
}, _callee9);
|
|
2252
|
+
}))();
|
|
2253
|
+
},
|
|
2254
|
+
requestNewSession: function requestNewSession(profileId) {
|
|
2464
2255
|
var _this20 = this;
|
|
2256
|
+
if (this.pendingSessionPromise) {
|
|
2257
|
+
return this.pendingSessionPromise;
|
|
2258
|
+
}
|
|
2259
|
+
if (!profileId || !this.connection) {
|
|
2260
|
+
return Promise.resolve(null);
|
|
2261
|
+
}
|
|
2262
|
+
this.pendingSessionPromise = new Promise(function (resolve, reject) {
|
|
2263
|
+
_this20.pendingSessionResolver = resolve;
|
|
2264
|
+
_this20.pendingSessionRejector = reject;
|
|
2265
|
+
_this20.pendingSessionTimeoutId = window.setTimeout(function () {
|
|
2266
|
+
_this20.rejectPendingSessionRequest('Timed out while creating a chat session.');
|
|
2267
|
+
}, 15000);
|
|
2268
|
+
});
|
|
2269
|
+
this.connection.invoke("StartSession", profileId, null)["catch"](function (err) {
|
|
2270
|
+
_this20.rejectPendingSessionRequest(err);
|
|
2271
|
+
});
|
|
2272
|
+
return this.pendingSessionPromise;
|
|
2273
|
+
},
|
|
2274
|
+
resolvePendingSessionRequest: function resolvePendingSessionRequest(sessionId) {
|
|
2275
|
+
if (this.pendingSessionResolver) {
|
|
2276
|
+
this.pendingSessionResolver(sessionId);
|
|
2277
|
+
}
|
|
2278
|
+
this.clearPendingSessionRequest();
|
|
2279
|
+
},
|
|
2280
|
+
rejectPendingSessionRequest: function rejectPendingSessionRequest(error) {
|
|
2281
|
+
if (this.pendingSessionRejector) {
|
|
2282
|
+
this.pendingSessionRejector(error);
|
|
2283
|
+
}
|
|
2284
|
+
this.clearPendingSessionRequest();
|
|
2285
|
+
},
|
|
2286
|
+
clearPendingSessionRequest: function clearPendingSessionRequest() {
|
|
2287
|
+
if (this.pendingSessionTimeoutId) {
|
|
2288
|
+
window.clearTimeout(this.pendingSessionTimeoutId);
|
|
2289
|
+
}
|
|
2290
|
+
this.pendingSessionPromise = null;
|
|
2291
|
+
this.pendingSessionResolver = null;
|
|
2292
|
+
this.pendingSessionRejector = null;
|
|
2293
|
+
this.pendingSessionTimeoutId = null;
|
|
2294
|
+
},
|
|
2295
|
+
initializeApp: function initializeApp() {
|
|
2296
|
+
var _this21 = this;
|
|
2465
2297
|
this.inputElement = document.querySelector(config.inputElementSelector);
|
|
2466
2298
|
this.buttonElement = document.querySelector(config.sendButtonElementSelector);
|
|
2467
2299
|
this.chatContainer = document.querySelector(config.chatContainerElementSelector);
|
|
2468
2300
|
this.placeholder = document.querySelector(config.placeholderElementSelector);
|
|
2301
|
+
if (!this.inputElement || !this.buttonElement || !this.chatContainer || !this.placeholder) {
|
|
2302
|
+
console.error('AI chat app could not initialize because one or more required elements were not found.', {
|
|
2303
|
+
inputElementSelector: config.inputElementSelector,
|
|
2304
|
+
sendButtonElementSelector: config.sendButtonElementSelector,
|
|
2305
|
+
chatContainerElementSelector: config.chatContainerElementSelector,
|
|
2306
|
+
placeholderElementSelector: config.placeholderElementSelector
|
|
2307
|
+
});
|
|
2308
|
+
return false;
|
|
2309
|
+
}
|
|
2469
2310
|
this.applyOrchestratorAvailability();
|
|
2470
2311
|
var sessionId = this.getSessionId();
|
|
2471
2312
|
if (!hasWidgetConfig && sessionId) {
|
|
@@ -2490,7 +2331,7 @@ window.openAIChatManager = function () {
|
|
|
2490
2331
|
fileInput.accept = config.allowedExtensions;
|
|
2491
2332
|
}
|
|
2492
2333
|
fileInput.addEventListener('change', function (e) {
|
|
2493
|
-
return
|
|
2334
|
+
return _this21.handleFileInputChange(e);
|
|
2494
2335
|
});
|
|
2495
2336
|
this.documentBar.parentElement.appendChild(fileInput);
|
|
2496
2337
|
|
|
@@ -2498,13 +2339,13 @@ window.openAIChatManager = function () {
|
|
|
2498
2339
|
var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;
|
|
2499
2340
|
if (inputArea) {
|
|
2500
2341
|
inputArea.addEventListener('dragover', function (e) {
|
|
2501
|
-
return
|
|
2342
|
+
return _this21.handleDragOver(e);
|
|
2502
2343
|
});
|
|
2503
2344
|
inputArea.addEventListener('dragleave', function (e) {
|
|
2504
|
-
return
|
|
2345
|
+
return _this21.handleDragLeave(e);
|
|
2505
2346
|
});
|
|
2506
2347
|
inputArea.addEventListener('drop', function (e) {
|
|
2507
|
-
return
|
|
2348
|
+
return _this21.handleDrop(e);
|
|
2508
2349
|
});
|
|
2509
2350
|
}
|
|
2510
2351
|
}
|
|
@@ -2512,55 +2353,55 @@ window.openAIChatManager = function () {
|
|
|
2512
2353
|
|
|
2513
2354
|
// Pause auto-scroll when the user manually scrolls up during streaming.
|
|
2514
2355
|
this.chatContainer.addEventListener('scroll', function () {
|
|
2515
|
-
if (!
|
|
2356
|
+
if (!_this21.stream) {
|
|
2516
2357
|
return;
|
|
2517
2358
|
}
|
|
2518
2359
|
var threshold = 30;
|
|
2519
|
-
var atBottom =
|
|
2520
|
-
|
|
2360
|
+
var atBottom = _this21.chatContainer.scrollHeight - _this21.chatContainer.clientHeight - _this21.chatContainer.scrollTop <= threshold;
|
|
2361
|
+
_this21.autoScroll = atBottom;
|
|
2521
2362
|
});
|
|
2522
2363
|
this.inputElement.addEventListener('keydown', function (event) {
|
|
2523
|
-
if (
|
|
2364
|
+
if (_this21.stream != null) {
|
|
2524
2365
|
return;
|
|
2525
2366
|
}
|
|
2526
2367
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
2527
2368
|
event.preventDefault();
|
|
2528
|
-
|
|
2369
|
+
_this21.buttonElement.click();
|
|
2529
2370
|
}
|
|
2530
2371
|
});
|
|
2531
2372
|
this.inputElement.addEventListener('input', function (e) {
|
|
2532
|
-
|
|
2373
|
+
_this21.handleUserInput(e);
|
|
2533
2374
|
if (e.target.value.trim()) {
|
|
2534
|
-
|
|
2375
|
+
_this21.buttonElement.removeAttribute('disabled');
|
|
2535
2376
|
} else {
|
|
2536
|
-
|
|
2377
|
+
_this21.buttonElement.setAttribute('disabled', true);
|
|
2537
2378
|
}
|
|
2538
2379
|
});
|
|
2539
2380
|
this.buttonElement.addEventListener('click', function () {
|
|
2540
|
-
if (
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2381
|
+
if (_this21.stream != null) {
|
|
2382
|
+
_this21.stream.dispose();
|
|
2383
|
+
_this21.stream = null;
|
|
2384
|
+
_this21.streamingFinished();
|
|
2385
|
+
_this21.hideTypingIndicator();
|
|
2545
2386
|
|
|
2546
2387
|
// Clean up: remove empty assistant message or stop streaming animation.
|
|
2547
|
-
if (
|
|
2548
|
-
var lastMsg =
|
|
2388
|
+
if (_this21.messages.length > 0) {
|
|
2389
|
+
var lastMsg = _this21.messages[_this21.messages.length - 1];
|
|
2549
2390
|
if (lastMsg.role === 'assistant' && !lastMsg.content) {
|
|
2550
|
-
|
|
2391
|
+
_this21.messages.pop();
|
|
2551
2392
|
} else if (lastMsg.isStreaming) {
|
|
2552
2393
|
lastMsg.isStreaming = false;
|
|
2553
2394
|
}
|
|
2554
2395
|
}
|
|
2555
2396
|
return;
|
|
2556
2397
|
}
|
|
2557
|
-
|
|
2398
|
+
_this21.sendMessage();
|
|
2558
2399
|
});
|
|
2559
2400
|
var promptGenerators = document.getElementsByClassName('profile-generated-prompt');
|
|
2560
2401
|
for (var i = 0; i < promptGenerators.length; i++) {
|
|
2561
2402
|
promptGenerators[i].addEventListener('click', function (e) {
|
|
2562
2403
|
e.preventDefault();
|
|
2563
|
-
|
|
2404
|
+
_this21.generatePrompt(e.target);
|
|
2564
2405
|
});
|
|
2565
2406
|
}
|
|
2566
2407
|
var chatSessions = document.getElementsByClassName('chat-session-history-item');
|
|
@@ -2572,8 +2413,8 @@ window.openAIChatManager = function () {
|
|
|
2572
2413
|
console.error('an element with the class chat-session-history-item with no data-session-id set.');
|
|
2573
2414
|
return;
|
|
2574
2415
|
}
|
|
2575
|
-
|
|
2576
|
-
|
|
2416
|
+
_this21.loadSession(sessionId);
|
|
2417
|
+
_this21.showChatScreen();
|
|
2577
2418
|
});
|
|
2578
2419
|
}
|
|
2579
2420
|
for (var _i5 = 0; _i5 < config.messages.length; _i5++) {
|
|
@@ -2582,7 +2423,7 @@ window.openAIChatManager = function () {
|
|
|
2582
2423
|
|
|
2583
2424
|
// Update feedback icons in the DOM after initial messages have rendered.
|
|
2584
2425
|
this.$nextTick(function () {
|
|
2585
|
-
|
|
2426
|
+
_this21.refreshAllFeedbackIcons();
|
|
2586
2427
|
});
|
|
2587
2428
|
|
|
2588
2429
|
// Delegate click for code block copy buttons.
|
|
@@ -2614,7 +2455,7 @@ window.openAIChatManager = function () {
|
|
|
2614
2455
|
if (this.micButton) {
|
|
2615
2456
|
this.micButton.style.display = '';
|
|
2616
2457
|
this.micButton.addEventListener('click', function () {
|
|
2617
|
-
|
|
2458
|
+
_this21.toggleRecording();
|
|
2618
2459
|
});
|
|
2619
2460
|
}
|
|
2620
2461
|
}
|
|
@@ -2624,10 +2465,11 @@ window.openAIChatManager = function () {
|
|
|
2624
2465
|
this.conversationButton = document.querySelector(config.conversationButtonElementSelector);
|
|
2625
2466
|
if (this.conversationButton) {
|
|
2626
2467
|
this.conversationButton.addEventListener('click', function () {
|
|
2627
|
-
|
|
2468
|
+
_this21.toggleConversationMode();
|
|
2628
2469
|
});
|
|
2629
2470
|
}
|
|
2630
2471
|
}
|
|
2472
|
+
return true;
|
|
2631
2473
|
},
|
|
2632
2474
|
loadSession: function loadSession(sessionId) {
|
|
2633
2475
|
this.connection.invoke("LoadSession", sessionId)["catch"](function (err) {
|
|
@@ -2642,6 +2484,9 @@ window.openAIChatManager = function () {
|
|
|
2642
2484
|
},
|
|
2643
2485
|
initializeSession: function initializeSession(sessionId, force) {
|
|
2644
2486
|
if (this.isSessionStarted && !force) {
|
|
2487
|
+
if (sessionId && this.getSessionId() === sessionId) {
|
|
2488
|
+
this.resolvePendingSessionRequest(sessionId);
|
|
2489
|
+
}
|
|
2645
2490
|
return;
|
|
2646
2491
|
}
|
|
2647
2492
|
this.fireEvent(new CustomEvent("initializingSessionOpenAIChat", {
|
|
@@ -2651,116 +2496,15 @@ window.openAIChatManager = function () {
|
|
|
2651
2496
|
}));
|
|
2652
2497
|
this.setSessionId(sessionId);
|
|
2653
2498
|
this.isSessionStarted = true;
|
|
2654
|
-
|
|
2655
|
-
|
|
2499
|
+
this.resolvePendingSessionRequest(sessionId);
|
|
2500
|
+
if (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {
|
|
2501
|
+
widgetBehavior.onSessionInitialized(this, sessionId, config);
|
|
2656
2502
|
}
|
|
2657
2503
|
},
|
|
2658
|
-
initializeWidget: function initializeWidget() {
|
|
2659
|
-
var _this21 = this;
|
|
2660
|
-
if (!config.widget.chatWidgetContainer) {
|
|
2661
|
-
console.error('The widget chatWidgetContainer is required.');
|
|
2662
|
-
return;
|
|
2663
|
-
}
|
|
2664
|
-
if (!config.widget.chatWidgetStateName) {
|
|
2665
|
-
console.error('The widget chatWidgetStateName is required.');
|
|
2666
|
-
return;
|
|
2667
|
-
}
|
|
2668
|
-
var chatWidgetContainer = document.querySelector(config.widget.chatWidgetContainer);
|
|
2669
|
-
if (!chatWidgetContainer) {
|
|
2670
|
-
return;
|
|
2671
|
-
}
|
|
2672
|
-
if (config.widget.chatHistorySection) {
|
|
2673
|
-
this.chatHistorySection = document.querySelector(config.widget.chatHistorySection);
|
|
2674
|
-
}
|
|
2675
|
-
this.chatWidgetStateName = config.widget.chatWidgetStateName;
|
|
2676
|
-
this.chatWidgetStateSession = config.widget.chatWidgetStateName + 'Session';
|
|
2677
|
-
this.chatWidgetLayoutKey = config.widget.chatWidgetStateName + 'Layout';
|
|
2678
|
-
this.widgetContainerElement = chatWidgetContainer;
|
|
2679
|
-
this.widgetToggleButtonElement = config.widget.toggleButtonSelector ? document.querySelector(config.widget.toggleButtonSelector) : null;
|
|
2680
|
-
this.widgetResetSizeButtonElement = config.widget.resetSizeButtonSelector ? document.querySelector(config.widget.resetSizeButtonSelector) : null;
|
|
2681
|
-
this.widgetDefaultWidth = parsePixelValue(config.widget.defaultWidth) || parsePixelValue(window.getComputedStyle(chatWidgetContainer).width) || 380;
|
|
2682
|
-
this.widgetDefaultHeight = parsePixelValue(config.widget.defaultHeight) || parsePixelValue(window.getComputedStyle(chatWidgetContainer).height) || 520;
|
|
2683
|
-
this.widgetIsInitialized = true;
|
|
2684
|
-
if (config.widget.enableResizing) {
|
|
2685
|
-
chatWidgetContainer.classList.add('ai-chat-widget-resizable');
|
|
2686
|
-
chatWidgetContainer.style.minWidth = (parsePixelValue(config.widget.minWidth) || 320) + 'px';
|
|
2687
|
-
chatWidgetContainer.style.minHeight = (parsePixelValue(config.widget.minHeight) || 420) + 'px';
|
|
2688
|
-
if (typeof ResizeObserver !== 'undefined') {
|
|
2689
|
-
this.widgetResizeObserver = new ResizeObserver(function () {
|
|
2690
|
-
_this21.persistWidgetPanelSize();
|
|
2691
|
-
_this21.constrainWidgetElementsToViewport();
|
|
2692
|
-
_this21.updateWidgetResetSizeButtonVisibility();
|
|
2693
|
-
});
|
|
2694
|
-
this.widgetResizeObserver.observe(chatWidgetContainer);
|
|
2695
|
-
}
|
|
2696
|
-
}
|
|
2697
|
-
var dragHandleSelector = config.widget.dragHandleSelector || '.ai-chat-widget-header';
|
|
2698
|
-
var dragHandle = chatWidgetContainer.querySelector(dragHandleSelector);
|
|
2699
|
-
if (config.widget.enableDragging && dragHandle) {
|
|
2700
|
-
dragHandle.classList.add('ai-chat-widget-drag-handle');
|
|
2701
|
-
chatWidgetContainer.classList.add('ai-chat-widget-draggable');
|
|
2702
|
-
this.attachDraggableWidgetElement(chatWidgetContainer, dragHandle, 'panel', false);
|
|
2703
|
-
}
|
|
2704
|
-
if (config.widget.enableDragging && this.widgetToggleButtonElement) {
|
|
2705
|
-
this.widgetToggleButtonElement.classList.add('ai-chat-widget-draggable');
|
|
2706
|
-
this.attachDraggableWidgetElement(this.widgetToggleButtonElement, this.widgetToggleButtonElement, 'toggle', true);
|
|
2707
|
-
}
|
|
2708
|
-
if (this.widgetResetSizeButtonElement) {
|
|
2709
|
-
this.widgetResetSizeButtonElement.addEventListener('click', function (event) {
|
|
2710
|
-
event.preventDefault();
|
|
2711
|
-
_this21.resetWidgetSize();
|
|
2712
|
-
});
|
|
2713
|
-
}
|
|
2714
|
-
this.restoreWidgetLayout();
|
|
2715
|
-
if (!this.widgetViewportResizeHandler) {
|
|
2716
|
-
this.widgetViewportResizeHandler = function () {
|
|
2717
|
-
_this21.constrainWidgetElementsToViewport();
|
|
2718
|
-
_this21.updateWidgetResetSizeButtonVisibility();
|
|
2719
|
-
};
|
|
2720
|
-
window.addEventListener('resize', this.widgetViewportResizeHandler);
|
|
2721
|
-
}
|
|
2722
|
-
|
|
2723
|
-
// Auto-load the last session so the user always sees previous chat history.
|
|
2724
|
-
this.reloadCurrentSession();
|
|
2725
|
-
if (config.autoCreateSession && !this.getSessionId()) {
|
|
2726
|
-
this.startNewSession();
|
|
2727
|
-
}
|
|
2728
|
-
if (config.widget.showHistoryButton && this.chatHistorySection) {
|
|
2729
|
-
var showHistoryButton = document.querySelector(config.widget.showHistoryButton);
|
|
2730
|
-
if (showHistoryButton) {
|
|
2731
|
-
showHistoryButton.addEventListener('click', function () {
|
|
2732
|
-
_this21.chatHistorySection.classList.toggle('show');
|
|
2733
|
-
});
|
|
2734
|
-
}
|
|
2735
|
-
if (config.widget.closeHistoryButton) {
|
|
2736
|
-
var closeHistoryButton = document.querySelector(config.widget.closeHistoryButton);
|
|
2737
|
-
if (closeHistoryButton) {
|
|
2738
|
-
closeHistoryButton.addEventListener('click', function () {
|
|
2739
|
-
_this21.showChatScreen();
|
|
2740
|
-
});
|
|
2741
|
-
}
|
|
2742
|
-
}
|
|
2743
|
-
}
|
|
2744
|
-
if (config.widget.newChatButton) {
|
|
2745
|
-
var newChatButton = document.querySelector(config.widget.newChatButton);
|
|
2746
|
-
if (newChatButton) {
|
|
2747
|
-
newChatButton.addEventListener('click', function () {
|
|
2748
|
-
_this21.resetSession();
|
|
2749
|
-
_this21.showChatScreen();
|
|
2750
|
-
});
|
|
2751
|
-
}
|
|
2752
|
-
}
|
|
2753
|
-
},
|
|
2754
|
-
showChatScreen: function showChatScreen() {
|
|
2755
|
-
if (!this.chatHistorySection) {
|
|
2756
|
-
return;
|
|
2757
|
-
}
|
|
2758
|
-
this.chatHistorySection.classList.remove('show');
|
|
2759
|
-
},
|
|
2760
2504
|
getSessionId: function getSessionId() {
|
|
2761
|
-
var sessionId = this.inputElement.getAttribute('data-session-id');
|
|
2762
|
-
if (!sessionId &&
|
|
2763
|
-
sessionId =
|
|
2505
|
+
var sessionId = this.inputElement ? this.inputElement.getAttribute('data-session-id') : null;
|
|
2506
|
+
if (!sessionId && widgetBehavior && typeof widgetBehavior.resolveSessionId === 'function') {
|
|
2507
|
+
sessionId = widgetBehavior.resolveSessionId(this, config);
|
|
2764
2508
|
}
|
|
2765
2509
|
return sessionId;
|
|
2766
2510
|
},
|
|
@@ -2844,12 +2588,18 @@ window.openAIChatManager = function () {
|
|
|
2844
2588
|
documents: {
|
|
2845
2589
|
handler: function handler() {
|
|
2846
2590
|
this.renderDocumentBar();
|
|
2591
|
+
if (widgetBehavior && typeof widgetBehavior.onDocumentsChanged === 'function') {
|
|
2592
|
+
widgetBehavior.onDocumentsChanged(this, this.documents, config);
|
|
2593
|
+
}
|
|
2847
2594
|
},
|
|
2848
2595
|
deep: true
|
|
2849
2596
|
},
|
|
2850
2597
|
isUploading: function isUploading() {
|
|
2851
2598
|
this.renderDocumentBar();
|
|
2852
2599
|
},
|
|
2600
|
+
isDocumentOperationPending: function isDocumentOperationPending() {
|
|
2601
|
+
this.renderDocumentBar();
|
|
2602
|
+
},
|
|
2853
2603
|
isPlayingAudio: function isPlayingAudio() {
|
|
2854
2604
|
// Reserved for future use — volume-based interrupt detection
|
|
2855
2605
|
// no longer mutes tracks; browser echo cancellation handles echo.
|
|
@@ -2876,21 +2626,22 @@ window.openAIChatManager = function () {
|
|
|
2876
2626
|
},
|
|
2877
2627
|
mounted: function mounted() {
|
|
2878
2628
|
var _this22 = this;
|
|
2879
|
-
_asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
2880
|
-
|
|
2881
|
-
|
|
2629
|
+
_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0() {
|
|
2630
|
+
var isInitialized;
|
|
2631
|
+
return _regenerator().w(function (_context0) {
|
|
2632
|
+
while (1) switch (_context0.n) {
|
|
2882
2633
|
case 0:
|
|
2883
|
-
|
|
2634
|
+
_context0.n = 1;
|
|
2884
2635
|
return _this22.startConnection();
|
|
2885
2636
|
case 1:
|
|
2886
|
-
_this22.initializeApp();
|
|
2887
|
-
if (hasWidgetConfig) {
|
|
2888
|
-
|
|
2637
|
+
isInitialized = _this22.initializeApp();
|
|
2638
|
+
if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {
|
|
2639
|
+
widgetBehavior.onMounted(_this22, config);
|
|
2889
2640
|
}
|
|
2890
2641
|
case 2:
|
|
2891
|
-
return
|
|
2642
|
+
return _context0.a(2);
|
|
2892
2643
|
}
|
|
2893
|
-
},
|
|
2644
|
+
}, _callee0);
|
|
2894
2645
|
}))();
|
|
2895
2646
|
window.addEventListener('beforeunload', this.handleBeforeUnload);
|
|
2896
2647
|
window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);
|
|
@@ -2906,9 +2657,16 @@ window.openAIChatManager = function () {
|
|
|
2906
2657
|
if (this.connection) {
|
|
2907
2658
|
this.connection.stop();
|
|
2908
2659
|
}
|
|
2660
|
+
if (widgetBehavior && typeof widgetBehavior.onBeforeUnmount === 'function') {
|
|
2661
|
+
widgetBehavior.onBeforeUnmount(this, config);
|
|
2662
|
+
}
|
|
2909
2663
|
},
|
|
2910
2664
|
template: config.messageTemplate
|
|
2911
|
-
}
|
|
2665
|
+
};
|
|
2666
|
+
var app = Vue.createApp(appDefinition).mount(config.appElementSelector);
|
|
2667
|
+
if (widgetBehavior && typeof widgetBehavior.attach === 'function') {
|
|
2668
|
+
widgetBehavior.attach(app, config);
|
|
2669
|
+
}
|
|
2912
2670
|
return app;
|
|
2913
2671
|
};
|
|
2914
2672
|
return {
|