@crestapps/ai-chat-ui 1.0.0-preview.10 → 1.0.0-preview.11

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.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 app = Vue.createApp({
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,
@@ -461,336 +450,6 @@ window.openAIChatManager = function () {
461
450
  handleBeforeUnload: function handleBeforeUnload() {
462
451
  this.isNavigatingAway = true;
463
452
  },
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
453
  handleDragOver: function handleDragOver(e) {
795
454
  if (!config.sessionDocumentsEnabled) return;
796
455
  e.preventDefault();
@@ -831,7 +490,7 @@ window.openAIChatManager = function () {
831
490
  e.target.value = '';
832
491
  },
833
492
  uploadFiles: function uploadFiles(files) {
834
- var _this2 = this;
493
+ var _this = this;
835
494
  return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
836
495
  var sessionId, profileId, formData, i, response, errorText, uploadError, result, j, _t;
837
496
  return _regenerator().w(function (_context) {
@@ -843,8 +502,8 @@ window.openAIChatManager = function () {
843
502
  }
844
503
  return _context.a(2);
845
504
  case 1:
846
- sessionId = _this2.getSessionId();
847
- profileId = _this2.getProfileId();
505
+ sessionId = _this.getSessionId();
506
+ profileId = _this.getProfileId();
848
507
  if (!(!sessionId && !profileId)) {
849
508
  _context.n = 2;
850
509
  break;
@@ -852,9 +511,9 @@ window.openAIChatManager = function () {
852
511
  console.warn('Cannot upload documents without a session or profile.');
853
512
  return _context.a(2);
854
513
  case 2:
855
- _this2.isUploading = true;
856
- _this2.uploadErrors = [];
857
- _this2.renderDocumentBar();
514
+ _this.isUploading = true;
515
+ _this.uploadErrors = [];
516
+ _this.renderDocumentBar();
858
517
  _context.p = 3;
859
518
  formData = new FormData();
860
519
  if (sessionId) {
@@ -880,9 +539,9 @@ window.openAIChatManager = function () {
880
539
  return response.text();
881
540
  case 5:
882
541
  errorText = _context.v;
883
- uploadError = _this2.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');
542
+ uploadError = _this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');
884
543
  console.error('Upload failed:', errorText);
885
- _this2.uploadErrors = [{
544
+ _this.uploadErrors = [{
886
545
  fileName: '',
887
546
  error: uploadError
888
547
  }];
@@ -894,15 +553,15 @@ window.openAIChatManager = function () {
894
553
  result = _context.v;
895
554
  // If the server created a new session, initialize it.
896
555
  if (result.sessionId && !sessionId) {
897
- _this2.initializeSession(result.sessionId);
556
+ _this.initializeSession(result.sessionId);
898
557
  }
899
558
  if (result.uploaded && result.uploaded.length > 0) {
900
559
  for (j = 0; j < result.uploaded.length; j++) {
901
- _this2.documents.push(result.uploaded[j]);
560
+ _this.documents.push(result.uploaded[j]);
902
561
  }
903
562
  }
904
563
  if (result.failed && result.failed.length > 0) {
905
- _this2.uploadErrors = result.failed;
564
+ _this.uploadErrors = result.failed;
906
565
  }
907
566
  _context.n = 9;
908
567
  break;
@@ -910,14 +569,14 @@ window.openAIChatManager = function () {
910
569
  _context.p = 8;
911
570
  _t = _context.v;
912
571
  console.error('Upload error:', _t);
913
- _this2.uploadErrors = [{
572
+ _this.uploadErrors = [{
914
573
  fileName: '',
915
574
  error: 'Upload failed. Please try again.'
916
575
  }];
917
576
  case 9:
918
577
  _context.p = 9;
919
- _this2.isUploading = false;
920
- _this2.renderDocumentBar();
578
+ _this.isUploading = false;
579
+ _this.renderDocumentBar();
921
580
  return _context.f(9);
922
581
  case 10:
923
582
  return _context.a(2);
@@ -926,7 +585,7 @@ window.openAIChatManager = function () {
926
585
  }))();
927
586
  },
928
587
  removeDocument: function removeDocument(doc) {
929
- var _this3 = this;
588
+ var _this2 = this;
930
589
  return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
931
590
  var sessionId, response, idx, errorText, removeError, _t2;
932
591
  return _regenerator().w(function (_context2) {
@@ -939,7 +598,7 @@ window.openAIChatManager = function () {
939
598
  return _context2.a(2);
940
599
  case 1:
941
600
  _context2.p = 1;
942
- sessionId = _this3.getSessionId();
601
+ sessionId = _this2.getSessionId();
943
602
  _context2.n = 2;
944
603
  return fetch(config.removeDocumentUrl, {
945
604
  method: 'POST',
@@ -957,8 +616,8 @@ window.openAIChatManager = function () {
957
616
  _context2.n = 3;
958
617
  break;
959
618
  }
960
- idx = _this3.documents.indexOf(doc);
961
- if (idx > -1) _this3.documents.splice(idx, 1);
619
+ idx = _this2.documents.indexOf(doc);
620
+ if (idx > -1) _this2.documents.splice(idx, 1);
962
621
  _context2.n = 5;
963
622
  break;
964
623
  case 3:
@@ -966,13 +625,13 @@ window.openAIChatManager = function () {
966
625
  return response.text();
967
626
  case 4:
968
627
  errorText = _context2.v;
969
- removeError = _this3.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');
628
+ removeError = _this2.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');
970
629
  console.error('Failed to remove document:', response.status, errorText);
971
- _this3.uploadErrors = [{
630
+ _this2.uploadErrors = [{
972
631
  fileName: doc.fileName || '',
973
632
  error: removeError
974
633
  }];
975
- _this3.renderDocumentBar();
634
+ _this2.renderDocumentBar();
976
635
  case 5:
977
636
  _context2.n = 7;
978
637
  break;
@@ -980,11 +639,11 @@ window.openAIChatManager = function () {
980
639
  _context2.p = 6;
981
640
  _t2 = _context2.v;
982
641
  console.error('Remove document error:', _t2);
983
- _this3.uploadErrors = [{
642
+ _this2.uploadErrors = [{
984
643
  fileName: doc.fileName || '',
985
644
  error: 'Failed to remove document. Please try again.'
986
645
  }];
987
- _this3.renderDocumentBar();
646
+ _this2.renderDocumentBar();
988
647
  case 7:
989
648
  return _context2.a(2);
990
649
  }
@@ -1154,139 +813,135 @@ window.openAIChatManager = function () {
1154
813
  return !!message && message.isStreaming && index === this.lastAssistantIndex && !(appearance && appearance.disableStreamingAnimation);
1155
814
  },
1156
815
  startConnection: function startConnection() {
1157
- var _this4 = this;
816
+ var _this3 = this;
1158
817
  return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
1159
818
  var _t3;
1160
819
  return _regenerator().w(function (_context3) {
1161
820
  while (1) switch (_context3.p = _context3.n) {
1162
821
  case 0:
1163
- _this4.connection = new signalR.HubConnectionBuilder().withUrl(config.signalRHubUrl).withAutomaticReconnect().build();
822
+ _this3.connection = new signalR.HubConnectionBuilder().withUrl(config.signalRHubUrl).withAutomaticReconnect().build();
1164
823
 
1165
824
  // Allow long-running operations (e.g., multi-step MCP tool calls)
1166
825
  // without the client disconnecting prematurely.
1167
- _this4.connection.serverTimeoutInMilliseconds = 600000;
1168
- _this4.connection.keepAliveIntervalInMilliseconds = 15000;
1169
- _this4.connection.on("LoadSession", function (data) {
826
+ _this3.connection.serverTimeoutInMilliseconds = 600000;
827
+ _this3.connection.keepAliveIntervalInMilliseconds = 15000;
828
+ _this3.connection.on("LoadSession", function (data) {
1170
829
  var _data$messages;
1171
- _this4.initializeSession(data.sessionId, true);
1172
- _this4.messages = [];
1173
- _this4.documents = data.documents || [];
830
+ _this3.initializeSession(data.sessionId, true);
831
+ _this3.messages = [];
832
+ _this3.documents = data.documents || [];
833
+ _this3.uploadErrors = [];
1174
834
  ((_data$messages = data.messages) !== null && _data$messages !== void 0 ? _data$messages : []).forEach(function (msg) {
1175
- _this4.addMessage(msg);
1176
- _this4.$nextTick(function () {
835
+ _this3.addMessage(msg);
836
+ _this3.$nextTick(function () {
1177
837
  renderChartsInMessage(msg);
1178
838
  });
1179
839
  });
1180
840
 
1181
841
  // Update feedback icons in the DOM after all messages have rendered.
1182
- _this4.$nextTick(function () {
1183
- _this4.refreshAllFeedbackIcons();
842
+ _this3.$nextTick(function () {
843
+ _this3.refreshAllFeedbackIcons();
1184
844
  });
1185
845
 
1186
846
  // When the session is new (no messages) and an initial prompt is configured,
1187
847
  // automatically send it as the first user message to trigger an AI response.
1188
- if (_this4.messages.length === 0 && config.initialPrompt) {
1189
- _this4.prompt = config.initialPrompt;
1190
- _this4.sendMessage();
848
+ if (_this3.messages.length === 0 && config.initialPrompt) {
849
+ _this3.prompt = config.initialPrompt;
850
+ _this3.sendMessage();
1191
851
  }
1192
852
  });
1193
- _this4.connection.on("ReceiveError", function (error) {
853
+ _this3.connection.on("ReceiveError", function (error) {
1194
854
  console.error("SignalR Error: ", error);
1195
- if (_this4.isRecording) {
1196
- _this4.stopRecording();
855
+ if (_this3.isRecording) {
856
+ _this3.stopRecording();
1197
857
  }
1198
-
1199
- // If this is a widget with a stale cached session (e.g., profile was deleted),
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();
858
+ if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {
859
+ widgetBehavior.handleReceiveError(_this3, error, config);
1205
860
  }
1206
861
  });
1207
- _this4.connection.on("MessageRated", function (messageId, userRating) {
1208
- var msg = _this4.messages.find(function (m) {
862
+ _this3.connection.on("MessageRated", function (messageId, userRating) {
863
+ var msg = _this3.messages.find(function (m) {
1209
864
  return m.id === messageId;
1210
865
  });
1211
866
  if (msg) {
1212
867
  msg.userRating = userRating;
1213
868
  }
1214
869
  });
1215
- _this4.connection.on("ReceiveTranscript", function (sessionId, text, isFinal) {
1216
- if (_this4.isConversationMode) {
870
+ _this3.connection.on("ReceiveTranscript", function (sessionId, text, isFinal) {
871
+ if (_this3.isConversationMode) {
1217
872
  if (!isFinal && text) {
1218
- _this4._conversationPartialTranscript = text;
873
+ _this3._conversationPartialTranscript = text;
1219
874
  var escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
1220
875
  var html = '<p class="ai-partial-transcript">' + escaped + '</p>';
1221
876
 
1222
877
  // Show partial transcript as a live user message.
1223
- if (!_this4._conversationPartialMessage) {
1224
- _this4.hidePlaceholder();
1225
- _this4._conversationPartialMessage = {
878
+ if (!_this3._conversationPartialMessage) {
879
+ _this3.hidePlaceholder();
880
+ _this3._conversationPartialMessage = {
1226
881
  role: 'user',
1227
882
  content: text,
1228
883
  htmlContent: html,
1229
884
  isPartial: true
1230
885
  };
1231
- _this4.messages.push(_this4._conversationPartialMessage);
886
+ _this3.messages.push(_this3._conversationPartialMessage);
1232
887
  } else {
1233
- _this4._conversationPartialMessage.content = text;
1234
- _this4._conversationPartialMessage.htmlContent = html;
888
+ _this3._conversationPartialMessage.content = text;
889
+ _this3._conversationPartialMessage.htmlContent = html;
1235
890
  }
1236
- _this4.scrollToBottom();
891
+ _this3.scrollToBottom();
1237
892
  }
1238
893
  return;
1239
894
  }
1240
- if (text && !_this4._audioInputSent) {
1241
- _this4.prompt = _this4.preRecordingPrompt + text;
1242
- if (_this4.inputElement) {
1243
- _this4.inputElement.value = _this4.prompt;
1244
- _this4.inputElement.dispatchEvent(new Event('input'));
895
+ if (text && !_this3._audioInputSent) {
896
+ _this3.prompt = _this3.preRecordingPrompt + text;
897
+ if (_this3.inputElement) {
898
+ _this3.inputElement.value = _this3.prompt;
899
+ _this3.inputElement.dispatchEvent(new Event('input'));
1245
900
  }
1246
901
  }
1247
902
  });
1248
- _this4.connection.on("ReceiveConversationUserMessage", function (sessionId, text) {
903
+ _this3.connection.on("ReceiveConversationUserMessage", function (sessionId, text) {
1249
904
  if (text) {
1250
- _this4.stopAudio();
905
+ _this3.stopAudio();
1251
906
 
1252
907
  // If there's an interrupted assistant message still streaming,
1253
908
  // mark it as done to stop the spinner animation.
1254
- if (_this4._conversationAssistantMessage) {
1255
- var oldMsg = _this4.messages[_this4._conversationAssistantMessage.index];
909
+ if (_this3._conversationAssistantMessage) {
910
+ var oldMsg = _this3.messages[_this3._conversationAssistantMessage.index];
1256
911
  if (oldMsg) {
1257
912
  oldMsg.isStreaming = false;
1258
913
  }
1259
- _this4._conversationAssistantMessage = null;
914
+ _this3._conversationAssistantMessage = null;
1260
915
  }
1261
916
 
1262
917
  // Replace the partial transcript message with the final one.
1263
- if (_this4._conversationPartialMessage) {
918
+ if (_this3._conversationPartialMessage) {
1264
919
  var escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
1265
- _this4._conversationPartialMessage.content = text;
1266
- _this4._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';
1267
- _this4._conversationPartialMessage.isPartial = false;
1268
- _this4._conversationPartialMessage = null;
920
+ _this3._conversationPartialMessage.content = text;
921
+ _this3._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';
922
+ _this3._conversationPartialMessage.isPartial = false;
923
+ _this3._conversationPartialMessage = null;
1269
924
  } else {
1270
- _this4.addMessage({
925
+ _this3.addMessage({
1271
926
  role: 'user',
1272
927
  content: text
1273
928
  });
1274
929
  }
1275
- _this4.scrollToBottom();
930
+ _this3.scrollToBottom();
1276
931
  }
1277
932
  });
1278
- _this4.connection.on("ReceiveConversationAssistantToken", function (sessionId, messageId, token, responseId, appearance) {
1279
- if (!_this4._conversationAssistantMessage) {
1280
- _this4.stopAudio();
1281
- _this4.hideTypingIndicator();
933
+ _this3.connection.on("ReceiveConversationAssistantToken", function (sessionId, messageId, token, responseId, appearance) {
934
+ if (!_this3._conversationAssistantMessage) {
935
+ _this3.stopAudio();
936
+ _this3.hideTypingIndicator();
1282
937
 
1283
938
  // Ensure no stale streaming indicators remain from prior messages.
1284
- for (var j = 0; j < _this4.messages.length; j++) {
1285
- if (_this4.messages[j].isStreaming) {
1286
- _this4.messages[j].isStreaming = false;
939
+ for (var j = 0; j < _this3.messages.length; j++) {
940
+ if (_this3.messages[j].isStreaming) {
941
+ _this3.messages[j].isStreaming = false;
1287
942
  }
1288
943
  }
1289
- var msgIndex = _this4.messages.length;
944
+ var msgIndex = _this3.messages.length;
1290
945
  var newMessage = {
1291
946
  id: messageId,
1292
947
  role: "assistant",
@@ -1294,72 +949,72 @@ window.openAIChatManager = function () {
1294
949
  htmlContent: "",
1295
950
  isStreaming: true,
1296
951
  userRating: null,
1297
- appearance: _this4.normalizeAssistantAppearance(appearance)
952
+ appearance: _this3.normalizeAssistantAppearance(appearance)
1298
953
  };
1299
- _this4.messages.push(newMessage);
1300
- _this4._conversationAssistantMessage = {
954
+ _this3.messages.push(newMessage);
955
+ _this3._conversationAssistantMessage = {
1301
956
  index: msgIndex,
1302
957
  content: ''
1303
958
  };
1304
959
  }
1305
- _this4._conversationAssistantMessage.content += token;
1306
- var msg = _this4.messages[_this4._conversationAssistantMessage.index];
960
+ _this3._conversationAssistantMessage.content += token;
961
+ var msg = _this3.messages[_this3._conversationAssistantMessage.index];
1307
962
  if (msg) {
1308
963
  if (!msg.appearance) {
1309
- msg.appearance = _this4.normalizeAssistantAppearance(appearance);
964
+ msg.appearance = _this3.normalizeAssistantAppearance(appearance);
1310
965
  }
1311
- msg.content = _this4._conversationAssistantMessage.content;
966
+ msg.content = _this3._conversationAssistantMessage.content;
1312
967
  msg.htmlContent = parseMarkdownContent(msg.content, msg);
1313
- _this4.$nextTick(function () {
968
+ _this3.$nextTick(function () {
1314
969
  renderChartsInMessage(msg);
1315
- _this4.scrollToBottom();
970
+ _this3.scrollToBottom();
1316
971
  });
1317
972
  }
1318
973
  });
1319
- _this4.connection.on("ReceiveConversationAssistantComplete", function (sessionId, messageId) {
1320
- if (_this4._conversationAssistantMessage) {
1321
- var msg = _this4.messages[_this4._conversationAssistantMessage.index];
974
+ _this3.connection.on("ReceiveConversationAssistantComplete", function (sessionId, messageId) {
975
+ if (_this3._conversationAssistantMessage) {
976
+ var msg = _this3.messages[_this3._conversationAssistantMessage.index];
1322
977
  if (msg) {
1323
978
  msg.isStreaming = false;
1324
979
  }
1325
- _this4._conversationAssistantMessage = null;
980
+ _this3._conversationAssistantMessage = null;
1326
981
  }
1327
982
  });
1328
- _this4.connection.on("ReceiveAudioChunk", function (sessionId, base64Audio, contentType) {
983
+ _this3.connection.on("ReceiveAudioChunk", function (sessionId, base64Audio, contentType) {
1329
984
  if (base64Audio) {
1330
985
  var binaryString = atob(base64Audio);
1331
986
  var bytes = new Uint8Array(binaryString.length);
1332
987
  for (var i = 0; i < binaryString.length; i++) {
1333
988
  bytes[i] = binaryString.charCodeAt(i);
1334
989
  }
1335
- _this4.audioChunks.push(bytes);
990
+ _this3.audioChunks.push(bytes);
1336
991
  }
1337
992
  });
1338
- _this4.connection.on("ReceiveAudioComplete", function (sessionId) {
1339
- _this4.playCollectedAudio();
993
+ _this3.connection.on("ReceiveAudioComplete", function (sessionId) {
994
+ _this3.playCollectedAudio();
1340
995
  });
1341
- _this4.connection.on("ReceiveNotification", function (notification) {
1342
- _this4.receiveNotification(notification);
996
+ _this3.connection.on("ReceiveNotification", function (notification) {
997
+ _this3.receiveNotification(notification);
1343
998
  });
1344
- _this4.connection.on("UpdateNotification", function (notification) {
1345
- _this4.updateNotification(notification);
999
+ _this3.connection.on("UpdateNotification", function (notification) {
1000
+ _this3.updateNotification(notification);
1346
1001
  });
1347
- _this4.connection.on("RemoveNotification", function (notificationType) {
1348
- _this4.removeNotification(notificationType);
1002
+ _this3.connection.on("RemoveNotification", function (notificationType) {
1003
+ _this3.removeNotification(notificationType);
1349
1004
  });
1350
- _this4.connection.onreconnecting(function () {
1005
+ _this3.connection.onreconnecting(function () {
1351
1006
  console.warn("SignalR: reconnecting...");
1352
1007
  });
1353
- _this4.connection.onreconnected(function () {
1008
+ _this3.connection.onreconnected(function () {
1354
1009
  console.info("SignalR: reconnected.");
1355
- if (_this4.isSessionStarted) {
1356
- _this4.reloadCurrentSession();
1010
+ if (_this3.isSessionStarted) {
1011
+ _this3.reloadCurrentSession();
1357
1012
  } else if (config.autoCreateSession) {
1358
- _this4.startNewSession();
1013
+ _this3.startNewSession();
1359
1014
  }
1360
1015
  });
1361
- _this4.connection.onclose(function (error) {
1362
- if (_this4.isNavigatingAway) {
1016
+ _this3.connection.onclose(function (error) {
1017
+ if (_this3.isNavigatingAway) {
1363
1018
  return;
1364
1019
  }
1365
1020
  if (error) {
@@ -1368,7 +1023,7 @@ window.openAIChatManager = function () {
1368
1023
  });
1369
1024
  _context3.p = 1;
1370
1025
  _context3.n = 2;
1371
- return _this4.connection.start();
1026
+ return _this3.connection.start();
1372
1027
  case 2:
1373
1028
  _context3.n = 4;
1374
1029
  break;
@@ -1383,7 +1038,7 @@ window.openAIChatManager = function () {
1383
1038
  }))();
1384
1039
  },
1385
1040
  addMessageInternal: function addMessageInternal(message) {
1386
- var _this5 = this;
1041
+ var _this4 = this;
1387
1042
  if (message.role === 'assistant') {
1388
1043
  message.appearance = this.normalizeAssistantAppearance(message.appearance);
1389
1044
  }
@@ -1397,7 +1052,7 @@ window.openAIChatManager = function () {
1397
1052
  }));
1398
1053
  this.messages.push(message);
1399
1054
  this.$nextTick(function () {
1400
- _this5.fireEvent(new CustomEvent("addedOpenAIPromotMessage", {
1055
+ _this4.fireEvent(new CustomEvent("addedOpenAIPromotMessage", {
1401
1056
  detail: {
1402
1057
  message: message
1403
1058
  }
@@ -1405,7 +1060,7 @@ window.openAIChatManager = function () {
1405
1060
  });
1406
1061
  },
1407
1062
  addMessage: function addMessage(message) {
1408
- var _this6 = this;
1063
+ var _this5 = this;
1409
1064
  // Ensure userRating is always defined for Vue reactivity.
1410
1065
  if (message.userRating === undefined) {
1411
1066
  message.userRating = null;
@@ -1493,17 +1148,17 @@ window.openAIChatManager = function () {
1493
1148
  this.$nextTick(function () {
1494
1149
  // Render any pending charts once the DOM is updated
1495
1150
  renderChartsInMessage(message);
1496
- _this6.scrollToBottom();
1151
+ _this5.scrollToBottom();
1497
1152
  });
1498
1153
  },
1499
1154
  addMessages: function addMessages(messages) {
1500
- var _this7 = this;
1155
+ var _this6 = this;
1501
1156
  for (var i = 0; i < messages.length; i++) {
1502
1157
  this.addMessageInternal(messages[i]);
1503
1158
  }
1504
1159
  this.hidePlaceholder();
1505
1160
  this.$nextTick(function () {
1506
- _this7.scrollToBottom();
1161
+ _this6.scrollToBottom();
1507
1162
  });
1508
1163
  },
1509
1164
  hidePlaceholder: function hidePlaceholder() {
@@ -1580,7 +1235,7 @@ window.openAIChatManager = function () {
1580
1235
  this.prompt = '';
1581
1236
  },
1582
1237
  startRecording: function startRecording() {
1583
- var _this8 = this;
1238
+ var _this7 = this;
1584
1239
  if (this.isRecording || !this.connection) {
1585
1240
  return;
1586
1241
  }
@@ -1592,17 +1247,17 @@ window.openAIChatManager = function () {
1592
1247
  }
1593
1248
  }).then(function (stream) {
1594
1249
  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
- _this8.mediaRecorder = new MediaRecorder(stream, {
1250
+ _this7.mediaRecorder = new MediaRecorder(stream, {
1596
1251
  mimeType: mimeType,
1597
1252
  audioBitsPerSecond: 128000
1598
1253
  });
1599
- _this8.preRecordingPrompt = _this8.prompt;
1600
- _this8._audioInputSent = false;
1254
+ _this7.preRecordingPrompt = _this7.prompt;
1255
+ _this7._audioInputSent = false;
1601
1256
  var subject = new signalR.Subject();
1602
- var profileId = _this8.getProfileId();
1603
- var sessionId = _this8.getSessionId() || '';
1257
+ var profileId = _this7.getProfileId();
1258
+ var sessionId = _this7.getSessionId() || '';
1604
1259
  var pendingChunk = Promise.resolve();
1605
- _this8.mediaRecorder.addEventListener('dataavailable', function (e) {
1260
+ _this7.mediaRecorder.addEventListener('dataavailable', function (e) {
1606
1261
  if (e.data && e.data.size > 0) {
1607
1262
  pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
1608
1263
  var data, uint8Array, binaryString, base64;
@@ -1626,7 +1281,7 @@ window.openAIChatManager = function () {
1626
1281
  })));
1627
1282
  }
1628
1283
  });
1629
- _this8.mediaRecorder.addEventListener('stop', function () {
1284
+ _this7.mediaRecorder.addEventListener('stop', function () {
1630
1285
  stream.getTracks().forEach(function (track) {
1631
1286
  return track.stop();
1632
1287
  });
@@ -1635,10 +1290,10 @@ window.openAIChatManager = function () {
1635
1290
  });
1636
1291
  });
1637
1292
  var language = navigator.language || document.documentElement.lang || 'en-US';
1638
- _this8.connection.send("SendAudioStream", profileId, sessionId, subject, mimeType, language);
1639
- _this8.mediaRecorder.start(250);
1640
- _this8.isRecording = true;
1641
- _this8.updateMicButton();
1293
+ _this7.connection.send("SendAudioStream", profileId, sessionId, subject, mimeType, language);
1294
+ _this7.mediaRecorder.start(250);
1295
+ _this7.isRecording = true;
1296
+ _this7.updateMicButton();
1642
1297
  })["catch"](function (err) {
1643
1298
  console.error('Microphone access denied:', err);
1644
1299
  });
@@ -1671,7 +1326,7 @@ window.openAIChatManager = function () {
1671
1326
  }
1672
1327
  },
1673
1328
  streamMessage: function streamMessage(profileId, trimmedPrompt, sessionProfileId) {
1674
- var _this9 = this;
1329
+ var _this8 = this;
1675
1330
  if (this.stream) {
1676
1331
  this.stream.dispose();
1677
1332
  this.stream = null;
@@ -1688,14 +1343,14 @@ window.openAIChatManager = function () {
1688
1343
  var currentSessionId = this.getSessionId();
1689
1344
  this.stream = this.connection.stream("SendMessage", profileId, trimmedPrompt, currentSessionId, sessionProfileId).subscribe({
1690
1345
  next: function next(chunk) {
1691
- var message = _this9.messages[messageIndex];
1346
+ var message = _this8.messages[messageIndex];
1692
1347
  if (!message) {
1693
1348
  if (chunk.sessionId && !currentSessionId) {
1694
- _this9.initializeSession(chunk.sessionId);
1349
+ _this8.initializeSession(chunk.sessionId);
1695
1350
  }
1696
- _this9.hideTypingIndicator();
1351
+ _this8.hideTypingIndicator();
1697
1352
  // Re-assign the index after hiding the typing indicator.
1698
- messageIndex = _this9.messages.length;
1353
+ messageIndex = _this8.messages.length;
1699
1354
  var newMessage = {
1700
1355
  id: chunk.messageId,
1701
1356
  role: "assistant",
@@ -1705,7 +1360,7 @@ window.openAIChatManager = function () {
1705
1360
  isStreaming: true,
1706
1361
  userRating: null
1707
1362
  };
1708
- _this9.messages.push(newMessage);
1363
+ _this8.messages.push(newMessage);
1709
1364
  message = newMessage;
1710
1365
  }
1711
1366
  if (chunk.title && (!message.title || message.title !== chunk.title)) {
@@ -1745,46 +1400,46 @@ window.openAIChatManager = function () {
1745
1400
  // Update the existing message
1746
1401
  message.content = content;
1747
1402
  message.htmlContent = parseMarkdownContent(content, message);
1748
- _this9.messages[messageIndex] = message;
1749
- _this9.$nextTick(function () {
1403
+ _this8.messages[messageIndex] = message;
1404
+ _this8.$nextTick(function () {
1750
1405
  renderChartsInMessage(message);
1751
- _this9.scrollToBottom();
1406
+ _this8.scrollToBottom();
1752
1407
  });
1753
1408
  },
1754
1409
  complete: function complete() {
1755
- var _this9$stream;
1756
- _this9.processReferences(references, messageIndex);
1757
- _this9.streamingFinished();
1758
- var msg = _this9.messages[messageIndex];
1410
+ var _this8$stream;
1411
+ _this8.processReferences(references, messageIndex);
1412
+ _this8.streamingFinished();
1413
+ var msg = _this8.messages[messageIndex];
1759
1414
  if (msg) {
1760
1415
  msg.isStreaming = false;
1761
1416
  }
1762
1417
  if (!msg || !msg.content) {
1763
1418
  // No content received at all.
1764
- _this9.hideTypingIndicator();
1419
+ _this8.hideTypingIndicator();
1765
1420
  }
1766
1421
 
1767
1422
  // Trigger text-to-speech only in conversation mode.
1768
- if (_this9.isConversationMode && _this9.textToSpeechEnabled && msg && msg.content) {
1769
- _this9.synthesizeSpeech(msg.content);
1423
+ if (_this8.isConversationMode && _this8.textToSpeechEnabled && msg && msg.content) {
1424
+ _this8.synthesizeSpeech(msg.content);
1770
1425
  }
1771
- (_this9$stream = _this9.stream) === null || _this9$stream === void 0 || _this9$stream.dispose();
1772
- _this9.stream = null;
1426
+ (_this8$stream = _this8.stream) === null || _this8$stream === void 0 || _this8$stream.dispose();
1427
+ _this8.stream = null;
1773
1428
  },
1774
1429
  error: function error(err) {
1775
- var _this9$stream2;
1776
- _this9.processReferences(references, messageIndex);
1777
- _this9.streamingFinished();
1778
- var msg = _this9.messages[messageIndex];
1430
+ var _this8$stream2;
1431
+ _this8.processReferences(references, messageIndex);
1432
+ _this8.streamingFinished();
1433
+ var msg = _this8.messages[messageIndex];
1779
1434
  if (msg) {
1780
1435
  msg.isStreaming = false;
1781
1436
  }
1782
- _this9.hideTypingIndicator();
1783
- if (!_this9.isNavigatingAway) {
1784
- _this9.addMessage(_this9.getServiceDownMessage());
1437
+ _this8.hideTypingIndicator();
1438
+ if (!_this8.isNavigatingAway) {
1439
+ _this8.addMessage(_this8.getServiceDownMessage());
1785
1440
  }
1786
- (_this9$stream2 = _this9.stream) === null || _this9$stream2 === void 0 || _this9$stream2.dispose();
1787
- _this9.stream = null;
1441
+ (_this8$stream2 = _this8.stream) === null || _this8$stream2 === void 0 || _this8$stream2.dispose();
1442
+ _this8.stream = null;
1788
1443
  console.error("Stream error:", err);
1789
1444
  }
1790
1445
  });
@@ -1798,7 +1453,7 @@ window.openAIChatManager = function () {
1798
1453
  return newMessage;
1799
1454
  },
1800
1455
  processReferences: function processReferences(references, messageIndex) {
1801
- var _this0 = this;
1456
+ var _this9 = this;
1802
1457
  references = normalizeReferences(references);
1803
1458
  if (Object.keys(references).length) {
1804
1459
  var message = this.messages[messageIndex];
@@ -1883,7 +1538,7 @@ window.openAIChatManager = function () {
1883
1538
  this.messages[messageIndex] = message;
1884
1539
  this.$nextTick(function () {
1885
1540
  renderChartsInMessage(message);
1886
- _this0.scrollToBottom();
1541
+ _this9.scrollToBottom();
1887
1542
  });
1888
1543
  }
1889
1544
  },
@@ -1934,14 +1589,14 @@ window.openAIChatManager = function () {
1934
1589
  this.stopAudio(false);
1935
1590
  },
1936
1591
  updateTtsPlaybackButtons: function updateTtsPlaybackButtons() {
1937
- var _this1 = this;
1592
+ var _this0 = this;
1938
1593
  if (!this.chatContainer) {
1939
1594
  return;
1940
1595
  }
1941
1596
  var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');
1942
1597
  buttons.forEach(function (button) {
1943
1598
  var buttonIndex = Number(button.getAttribute('data-tts-message-index'));
1944
- var isPlaying = buttonIndex === _this1.ttsPlayingMessageIndex;
1599
+ var isPlaying = buttonIndex === _this0.ttsPlayingMessageIndex;
1945
1600
  var iconHtml = isPlaying ? '<span class="fa-solid fa-circle-pause"></span>' : '<span class="fa-solid fa-circle-play"></span>';
1946
1601
  button.classList.toggle('tts-playing', isPlaying);
1947
1602
  button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');
@@ -1951,7 +1606,7 @@ window.openAIChatManager = function () {
1951
1606
  });
1952
1607
  },
1953
1608
  synthesizeSpeech: function synthesizeSpeech(text, cacheIndex) {
1954
- var _this10 = this;
1609
+ var _this1 = this;
1955
1610
  if (!this.textToSpeechEnabled || !text || !this.connection) {
1956
1611
  return;
1957
1612
  }
@@ -1960,16 +1615,16 @@ window.openAIChatManager = function () {
1960
1615
  this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;
1961
1616
  this.connection.invoke("SynthesizeSpeech", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)["catch"](function (err) {
1962
1617
  console.error("TTS synthesis error:", err);
1963
- _this10.isPlayingAudio = false;
1964
- _this10.ttsPlayingMessageIndex = -1;
1965
- _this10._ttsCacheIndex = -1;
1966
- _this10.$nextTick(function () {
1967
- return _this10.updateTtsPlaybackButtons();
1618
+ _this1.isPlayingAudio = false;
1619
+ _this1.ttsPlayingMessageIndex = -1;
1620
+ _this1._ttsCacheIndex = -1;
1621
+ _this1.$nextTick(function () {
1622
+ return _this1.updateTtsPlaybackButtons();
1968
1623
  });
1969
1624
  });
1970
1625
  },
1971
1626
  toggleMessageTts: function toggleMessageTts(message, index) {
1972
- var _this11 = this;
1627
+ var _this10 = this;
1973
1628
  if (this.ttsPlayingMessageIndex === index) {
1974
1629
  this.stopAudio();
1975
1630
  return;
@@ -1982,7 +1637,7 @@ window.openAIChatManager = function () {
1982
1637
  }));
1983
1638
  this.ttsPlayingMessageIndex = index;
1984
1639
  this.$nextTick(function () {
1985
- return _this11.updateTtsPlaybackButtons();
1640
+ return _this10.updateTtsPlaybackButtons();
1986
1641
  });
1987
1642
  if (this.ttsAudioCache[index]) {
1988
1643
  this.playAudioBlob(this.ttsAudioCache[index]);
@@ -1991,13 +1646,13 @@ window.openAIChatManager = function () {
1991
1646
  this.synthesizeSpeech(message.content, index);
1992
1647
  },
1993
1648
  playCollectedAudio: function playCollectedAudio() {
1994
- var _this12 = this;
1649
+ var _this11 = this;
1995
1650
  if (this.audioChunks.length === 0) {
1996
1651
  if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {
1997
1652
  this.isPlayingAudio = false;
1998
1653
  this.ttsPlayingMessageIndex = -1;
1999
1654
  this.$nextTick(function () {
2000
- return _this12.updateTtsPlaybackButtons();
1655
+ return _this11.updateTtsPlaybackButtons();
2001
1656
  });
2002
1657
  }
2003
1658
  return;
@@ -2037,39 +1692,39 @@ window.openAIChatManager = function () {
2037
1692
  this.playAudioBlob(blob);
2038
1693
  },
2039
1694
  playAudioBlob: function playAudioBlob(blob) {
2040
- var _this13 = this;
1695
+ var _this12 = this;
2041
1696
  var url = URL.createObjectURL(blob);
2042
1697
  var audio = new Audio(url);
2043
1698
  this.currentAudioUrl = url;
2044
1699
  this.currentAudioElement = audio;
2045
1700
  this.isPlayingAudio = true;
2046
1701
  audio.addEventListener('ended', function () {
2047
- _this13.currentAudioElement = null;
2048
- _this13.currentAudioUrl = null;
1702
+ _this12.currentAudioElement = null;
1703
+ _this12.currentAudioUrl = null;
2049
1704
  URL.revokeObjectURL(url);
2050
- _this13.playNextInQueue();
1705
+ _this12.playNextInQueue();
2051
1706
  });
2052
1707
  audio.addEventListener('error', function () {
2053
- _this13.currentAudioElement = null;
2054
- _this13.currentAudioUrl = null;
1708
+ _this12.currentAudioElement = null;
1709
+ _this12.currentAudioUrl = null;
2055
1710
  URL.revokeObjectURL(url);
2056
- _this13.playNextInQueue();
1711
+ _this12.playNextInQueue();
2057
1712
  });
2058
1713
  audio.play()["catch"](function (err) {
2059
1714
  console.error("Audio playback error:", err);
2060
- _this13.currentAudioElement = null;
2061
- _this13.currentAudioUrl = null;
1715
+ _this12.currentAudioElement = null;
1716
+ _this12.currentAudioUrl = null;
2062
1717
  URL.revokeObjectURL(url);
2063
- _this13.audioPlayQueue = [];
2064
- _this13.isPlayingAudio = false;
2065
- _this13.ttsPlayingMessageIndex = -1;
2066
- _this13.$nextTick(function () {
2067
- return _this13.updateTtsPlaybackButtons();
1718
+ _this12.audioPlayQueue = [];
1719
+ _this12.isPlayingAudio = false;
1720
+ _this12.ttsPlayingMessageIndex = -1;
1721
+ _this12.$nextTick(function () {
1722
+ return _this12.updateTtsPlaybackButtons();
2068
1723
  });
2069
1724
  });
2070
1725
  },
2071
1726
  playNextInQueue: function playNextInQueue() {
2072
- var _this14 = this;
1727
+ var _this13 = this;
2073
1728
  if (this.audioPlayQueue.length > 0) {
2074
1729
  var nextBlob = this.audioPlayQueue.shift();
2075
1730
  this.playAudioBlob(nextBlob);
@@ -2077,13 +1732,13 @@ window.openAIChatManager = function () {
2077
1732
  this.isPlayingAudio = false;
2078
1733
  this.ttsPlayingMessageIndex = -1;
2079
1734
  this.$nextTick(function () {
2080
- return _this14.updateTtsPlaybackButtons();
1735
+ return _this13.updateTtsPlaybackButtons();
2081
1736
  });
2082
1737
  this.conversationModeOnAudioEnded();
2083
1738
  }
2084
1739
  },
2085
1740
  stopAudio: function stopAudio() {
2086
- var _this15 = this;
1741
+ var _this14 = this;
2087
1742
  if (this.currentAudioElement) {
2088
1743
  this.currentAudioElement.pause();
2089
1744
  this.currentAudioElement.currentTime = 0;
@@ -2098,7 +1753,7 @@ window.openAIChatManager = function () {
2098
1753
  this.isPlayingAudio = false;
2099
1754
  this.ttsPlayingMessageIndex = -1;
2100
1755
  this.$nextTick(function () {
2101
- return _this15.updateTtsPlaybackButtons();
1756
+ return _this14.updateTtsPlaybackButtons();
2102
1757
  });
2103
1758
  },
2104
1759
  toggleConversationMode: function toggleConversationMode() {
@@ -2109,7 +1764,7 @@ window.openAIChatManager = function () {
2109
1764
  }
2110
1765
  },
2111
1766
  startConversationMode: function startConversationMode() {
2112
- var _this16 = this;
1767
+ var _this15 = this;
2113
1768
  if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {
2114
1769
  return;
2115
1770
  }
@@ -2129,12 +1784,12 @@ window.openAIChatManager = function () {
2129
1784
  }
2130
1785
  }).then(function (stream) {
2131
1786
  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
- _this16.mediaRecorder = new MediaRecorder(stream, {
1787
+ _this15.mediaRecorder = new MediaRecorder(stream, {
2133
1788
  mimeType: mimeType,
2134
1789
  audioBitsPerSecond: 128000
2135
1790
  });
2136
- _this16._conversationSubject = new signalR.Subject();
2137
- _this16._conversationStream = stream;
1791
+ _this15._conversationSubject = new signalR.Subject();
1792
+ _this15._conversationStream = stream;
2138
1793
 
2139
1794
  // Create an AnalyserNode for volume-based interrupt detection.
2140
1795
  // During TTS playback, detect when the user speaks above
@@ -2143,20 +1798,20 @@ window.openAIChatManager = function () {
2143
1798
  // speaker echo so the STT stream has no gaps.
2144
1799
  var AudioCtx = window.AudioContext || window.webkitAudioContext;
2145
1800
  if (AudioCtx) {
2146
- _this16._conversationAudioCtx = new AudioCtx();
2147
- _this16._conversationAnalyser = _this16._conversationAudioCtx.createAnalyser();
2148
- _this16._conversationAnalyser.fftSize = 256;
2149
- var micSource = _this16._conversationAudioCtx.createMediaStreamSource(stream);
2150
- micSource.connect(_this16._conversationAnalyser);
1801
+ _this15._conversationAudioCtx = new AudioCtx();
1802
+ _this15._conversationAnalyser = _this15._conversationAudioCtx.createAnalyser();
1803
+ _this15._conversationAnalyser.fftSize = 256;
1804
+ var micSource = _this15._conversationAudioCtx.createMediaStreamSource(stream);
1805
+ micSource.connect(_this15._conversationAnalyser);
2151
1806
  }
2152
1807
  var pendingChunk = Promise.resolve();
2153
- var analyser = _this16._conversationAnalyser;
1808
+ var analyser = _this15._conversationAnalyser;
2154
1809
  var interruptVolumeThreshold = 30;
2155
- _this16.mediaRecorder.addEventListener('dataavailable', function (e) {
1810
+ _this15.mediaRecorder.addEventListener('dataavailable', function (e) {
2156
1811
  if (e.data && e.data.size > 0) {
2157
1812
  // During TTS playback, check mic volume to detect
2158
1813
  // user interruption (speaking above threshold).
2159
- if (_this16.isPlayingAudio && analyser) {
1814
+ if (_this15.isPlayingAudio && analyser) {
2160
1815
  var freqData = new Uint8Array(analyser.frequencyBinCount);
2161
1816
  analyser.getByteFrequencyData(freqData);
2162
1817
  var sum = 0;
@@ -2166,7 +1821,7 @@ window.openAIChatManager = function () {
2166
1821
  var avg = sum / freqData.length;
2167
1822
  if (avg >= interruptVolumeThreshold) {
2168
1823
  // User is speaking — interrupt TTS playback.
2169
- _this16.stopAudio();
1824
+ _this15.stopAudio();
2170
1825
  }
2171
1826
  }
2172
1827
 
@@ -2188,7 +1843,7 @@ window.openAIChatManager = function () {
2188
1843
  }, '');
2189
1844
  base64 = btoa(binaryString);
2190
1845
  try {
2191
- _this16._conversationSubject.next(base64);
1846
+ _this15._conversationSubject.next(base64);
2192
1847
  } catch (err) {
2193
1848
  // Subject may have been completed already.
2194
1849
  }
@@ -2199,28 +1854,28 @@ window.openAIChatManager = function () {
2199
1854
  })));
2200
1855
  }
2201
1856
  });
2202
- _this16.mediaRecorder.addEventListener('stop', function () {
1857
+ _this15.mediaRecorder.addEventListener('stop', function () {
2203
1858
  stream.getTracks().forEach(function (track) {
2204
1859
  return track.stop();
2205
1860
  });
2206
1861
  pendingChunk.then(function () {
2207
1862
  try {
2208
- _this16._conversationSubject.complete();
1863
+ _this15._conversationSubject.complete();
2209
1864
  } catch (err) {
2210
1865
  // Already completed.
2211
1866
  }
2212
1867
  });
2213
1868
  });
2214
- var profileId = _this16.getProfileId();
2215
- var sessionId = _this16.getSessionId() || '';
1869
+ var profileId = _this15.getProfileId();
1870
+ var sessionId = _this15.getSessionId() || '';
2216
1871
  var language = navigator.language || document.documentElement.lang || 'en-US';
2217
- _this16.connection.send("StartConversation", profileId, sessionId, _this16._conversationSubject, mimeType, language);
2218
- _this16.mediaRecorder.start(250);
2219
- _this16.isRecording = true;
1872
+ _this15.connection.send("StartConversation", profileId, sessionId, _this15._conversationSubject, mimeType, language);
1873
+ _this15.mediaRecorder.start(250);
1874
+ _this15.isRecording = true;
2220
1875
  })["catch"](function (err) {
2221
1876
  console.error('Microphone access denied:', err);
2222
- _this16.isConversationMode = false;
2223
- _this16.updateConversationButton();
1877
+ _this15.isConversationMode = false;
1878
+ _this15.updateConversationButton();
2224
1879
  });
2225
1880
  },
2226
1881
  stopConversationMode: function stopConversationMode() {
@@ -2347,7 +2002,7 @@ window.openAIChatManager = function () {
2347
2002
  return removedCount;
2348
2003
  },
2349
2004
  receiveNotification: function receiveNotification(notification) {
2350
- var _this17 = this;
2005
+ var _this16 = this;
2351
2006
  if (!notification || !notification.type) {
2352
2007
  return;
2353
2008
  }
@@ -2362,7 +2017,7 @@ window.openAIChatManager = function () {
2362
2017
  }
2363
2018
  this.scheduleNotificationDismiss(notification);
2364
2019
  this.$nextTick(function () {
2365
- _this17.scrollToBottom();
2020
+ _this16.scrollToBottom();
2366
2021
  });
2367
2022
  },
2368
2023
  updateNotification: function updateNotification(notification) {
@@ -2379,12 +2034,12 @@ window.openAIChatManager = function () {
2379
2034
  }
2380
2035
  },
2381
2036
  scheduleNotificationDismiss: function scheduleNotificationDismiss(notification) {
2382
- var _this18 = this;
2037
+ var _this17 = this;
2383
2038
  if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {
2384
2039
  return;
2385
2040
  }
2386
2041
  this.notificationDismissTimers[notification.type] = setTimeout(function () {
2387
- _this18.removeNotification(notification.type);
2042
+ _this17.removeNotification(notification.type);
2388
2043
  }, notification.autoDismissMs);
2389
2044
  },
2390
2045
  clearNotificationDismiss: function clearNotificationDismiss(notificationType) {
@@ -2414,12 +2069,12 @@ window.openAIChatManager = function () {
2414
2069
  });
2415
2070
  },
2416
2071
  scrollToBottom: function scrollToBottom() {
2417
- var _this19 = this;
2072
+ var _this18 = this;
2418
2073
  if (!this.autoScroll) {
2419
2074
  return;
2420
2075
  }
2421
2076
  setTimeout(function () {
2422
- _this19.chatContainer.scrollTop = _this19.chatContainer.scrollHeight - _this19.chatContainer.clientHeight;
2077
+ _this18.chatContainer.scrollTop = _this18.chatContainer.scrollHeight - _this18.chatContainer.clientHeight;
2423
2078
  }, 50);
2424
2079
  },
2425
2080
  handleUserInput: function handleUserInput(event) {
@@ -2436,9 +2091,6 @@ window.openAIChatManager = function () {
2436
2091
  this.setSessionId('');
2437
2092
  this.isSessionStarted = false;
2438
2093
  this.sessionRating = null;
2439
- if (this.widgetIsInitialized) {
2440
- localStorage.removeItem(this.chatWidgetStateSession);
2441
- }
2442
2094
  this.messages = [];
2443
2095
  this.documents = [];
2444
2096
  if (!config.autoCreateSession) {
@@ -2447,6 +2099,9 @@ window.openAIChatManager = function () {
2447
2099
  if (config.autoCreateSession) {
2448
2100
  this.startNewSession();
2449
2101
  }
2102
+ if (widgetBehavior && typeof widgetBehavior.onSessionReset === 'function') {
2103
+ widgetBehavior.onSessionReset(this, config);
2104
+ }
2450
2105
  },
2451
2106
  startNewSession: function startNewSession() {
2452
2107
  if (!this.applyOrchestratorAvailability()) {
@@ -2461,7 +2116,7 @@ window.openAIChatManager = function () {
2461
2116
  });
2462
2117
  },
2463
2118
  initializeApp: function initializeApp() {
2464
- var _this20 = this;
2119
+ var _this19 = this;
2465
2120
  this.inputElement = document.querySelector(config.inputElementSelector);
2466
2121
  this.buttonElement = document.querySelector(config.sendButtonElementSelector);
2467
2122
  this.chatContainer = document.querySelector(config.chatContainerElementSelector);
@@ -2490,7 +2145,7 @@ window.openAIChatManager = function () {
2490
2145
  fileInput.accept = config.allowedExtensions;
2491
2146
  }
2492
2147
  fileInput.addEventListener('change', function (e) {
2493
- return _this20.handleFileInputChange(e);
2148
+ return _this19.handleFileInputChange(e);
2494
2149
  });
2495
2150
  this.documentBar.parentElement.appendChild(fileInput);
2496
2151
 
@@ -2498,13 +2153,13 @@ window.openAIChatManager = function () {
2498
2153
  var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;
2499
2154
  if (inputArea) {
2500
2155
  inputArea.addEventListener('dragover', function (e) {
2501
- return _this20.handleDragOver(e);
2156
+ return _this19.handleDragOver(e);
2502
2157
  });
2503
2158
  inputArea.addEventListener('dragleave', function (e) {
2504
- return _this20.handleDragLeave(e);
2159
+ return _this19.handleDragLeave(e);
2505
2160
  });
2506
2161
  inputArea.addEventListener('drop', function (e) {
2507
- return _this20.handleDrop(e);
2162
+ return _this19.handleDrop(e);
2508
2163
  });
2509
2164
  }
2510
2165
  }
@@ -2512,55 +2167,55 @@ window.openAIChatManager = function () {
2512
2167
 
2513
2168
  // Pause auto-scroll when the user manually scrolls up during streaming.
2514
2169
  this.chatContainer.addEventListener('scroll', function () {
2515
- if (!_this20.stream) {
2170
+ if (!_this19.stream) {
2516
2171
  return;
2517
2172
  }
2518
2173
  var threshold = 30;
2519
- var atBottom = _this20.chatContainer.scrollHeight - _this20.chatContainer.clientHeight - _this20.chatContainer.scrollTop <= threshold;
2520
- _this20.autoScroll = atBottom;
2174
+ var atBottom = _this19.chatContainer.scrollHeight - _this19.chatContainer.clientHeight - _this19.chatContainer.scrollTop <= threshold;
2175
+ _this19.autoScroll = atBottom;
2521
2176
  });
2522
2177
  this.inputElement.addEventListener('keydown', function (event) {
2523
- if (_this20.stream != null) {
2178
+ if (_this19.stream != null) {
2524
2179
  return;
2525
2180
  }
2526
2181
  if (event.key === "Enter" && !event.shiftKey) {
2527
2182
  event.preventDefault();
2528
- _this20.buttonElement.click();
2183
+ _this19.buttonElement.click();
2529
2184
  }
2530
2185
  });
2531
2186
  this.inputElement.addEventListener('input', function (e) {
2532
- _this20.handleUserInput(e);
2187
+ _this19.handleUserInput(e);
2533
2188
  if (e.target.value.trim()) {
2534
- _this20.buttonElement.removeAttribute('disabled');
2189
+ _this19.buttonElement.removeAttribute('disabled');
2535
2190
  } else {
2536
- _this20.buttonElement.setAttribute('disabled', true);
2191
+ _this19.buttonElement.setAttribute('disabled', true);
2537
2192
  }
2538
2193
  });
2539
2194
  this.buttonElement.addEventListener('click', function () {
2540
- if (_this20.stream != null) {
2541
- _this20.stream.dispose();
2542
- _this20.stream = null;
2543
- _this20.streamingFinished();
2544
- _this20.hideTypingIndicator();
2195
+ if (_this19.stream != null) {
2196
+ _this19.stream.dispose();
2197
+ _this19.stream = null;
2198
+ _this19.streamingFinished();
2199
+ _this19.hideTypingIndicator();
2545
2200
 
2546
2201
  // Clean up: remove empty assistant message or stop streaming animation.
2547
- if (_this20.messages.length > 0) {
2548
- var lastMsg = _this20.messages[_this20.messages.length - 1];
2202
+ if (_this19.messages.length > 0) {
2203
+ var lastMsg = _this19.messages[_this19.messages.length - 1];
2549
2204
  if (lastMsg.role === 'assistant' && !lastMsg.content) {
2550
- _this20.messages.pop();
2205
+ _this19.messages.pop();
2551
2206
  } else if (lastMsg.isStreaming) {
2552
2207
  lastMsg.isStreaming = false;
2553
2208
  }
2554
2209
  }
2555
2210
  return;
2556
2211
  }
2557
- _this20.sendMessage();
2212
+ _this19.sendMessage();
2558
2213
  });
2559
2214
  var promptGenerators = document.getElementsByClassName('profile-generated-prompt');
2560
2215
  for (var i = 0; i < promptGenerators.length; i++) {
2561
2216
  promptGenerators[i].addEventListener('click', function (e) {
2562
2217
  e.preventDefault();
2563
- _this20.generatePrompt(e.target);
2218
+ _this19.generatePrompt(e.target);
2564
2219
  });
2565
2220
  }
2566
2221
  var chatSessions = document.getElementsByClassName('chat-session-history-item');
@@ -2572,8 +2227,8 @@ window.openAIChatManager = function () {
2572
2227
  console.error('an element with the class chat-session-history-item with no data-session-id set.');
2573
2228
  return;
2574
2229
  }
2575
- _this20.loadSession(sessionId);
2576
- _this20.showChatScreen();
2230
+ _this19.loadSession(sessionId);
2231
+ _this19.showChatScreen();
2577
2232
  });
2578
2233
  }
2579
2234
  for (var _i5 = 0; _i5 < config.messages.length; _i5++) {
@@ -2582,7 +2237,7 @@ window.openAIChatManager = function () {
2582
2237
 
2583
2238
  // Update feedback icons in the DOM after initial messages have rendered.
2584
2239
  this.$nextTick(function () {
2585
- _this20.refreshAllFeedbackIcons();
2240
+ _this19.refreshAllFeedbackIcons();
2586
2241
  });
2587
2242
 
2588
2243
  // Delegate click for code block copy buttons.
@@ -2614,7 +2269,7 @@ window.openAIChatManager = function () {
2614
2269
  if (this.micButton) {
2615
2270
  this.micButton.style.display = '';
2616
2271
  this.micButton.addEventListener('click', function () {
2617
- _this20.toggleRecording();
2272
+ _this19.toggleRecording();
2618
2273
  });
2619
2274
  }
2620
2275
  }
@@ -2624,7 +2279,7 @@ window.openAIChatManager = function () {
2624
2279
  this.conversationButton = document.querySelector(config.conversationButtonElementSelector);
2625
2280
  if (this.conversationButton) {
2626
2281
  this.conversationButton.addEventListener('click', function () {
2627
- _this20.toggleConversationMode();
2282
+ _this19.toggleConversationMode();
2628
2283
  });
2629
2284
  }
2630
2285
  }
@@ -2651,116 +2306,14 @@ window.openAIChatManager = function () {
2651
2306
  }));
2652
2307
  this.setSessionId(sessionId);
2653
2308
  this.isSessionStarted = true;
2654
- if (this.widgetIsInitialized) {
2655
- localStorage.setItem(this.chatWidgetStateSession, sessionId);
2309
+ if (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {
2310
+ widgetBehavior.onSessionInitialized(this, sessionId, config);
2656
2311
  }
2657
2312
  },
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
2313
  getSessionId: function getSessionId() {
2761
2314
  var sessionId = this.inputElement.getAttribute('data-session-id');
2762
- if (!sessionId && this.widgetIsInitialized) {
2763
- sessionId = localStorage.getItem(this.chatWidgetStateSession);
2315
+ if (!sessionId && widgetBehavior && typeof widgetBehavior.resolveSessionId === 'function') {
2316
+ sessionId = widgetBehavior.resolveSessionId(this, config);
2764
2317
  }
2765
2318
  return sessionId;
2766
2319
  },
@@ -2844,6 +2397,9 @@ window.openAIChatManager = function () {
2844
2397
  documents: {
2845
2398
  handler: function handler() {
2846
2399
  this.renderDocumentBar();
2400
+ if (widgetBehavior && typeof widgetBehavior.onDocumentsChanged === 'function') {
2401
+ widgetBehavior.onDocumentsChanged(this, this.documents, config);
2402
+ }
2847
2403
  },
2848
2404
  deep: true
2849
2405
  },
@@ -2875,17 +2431,17 @@ window.openAIChatManager = function () {
2875
2431
  }
2876
2432
  },
2877
2433
  mounted: function mounted() {
2878
- var _this22 = this;
2434
+ var _this20 = this;
2879
2435
  _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
2880
2436
  return _regenerator().w(function (_context6) {
2881
2437
  while (1) switch (_context6.n) {
2882
2438
  case 0:
2883
2439
  _context6.n = 1;
2884
- return _this22.startConnection();
2440
+ return _this20.startConnection();
2885
2441
  case 1:
2886
- _this22.initializeApp();
2887
- if (hasWidgetConfig) {
2888
- _this22.initializeWidget();
2442
+ _this20.initializeApp();
2443
+ if (hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {
2444
+ widgetBehavior.onMounted(_this20, config);
2889
2445
  }
2890
2446
  case 2:
2891
2447
  return _context6.a(2);
@@ -2906,9 +2462,16 @@ window.openAIChatManager = function () {
2906
2462
  if (this.connection) {
2907
2463
  this.connection.stop();
2908
2464
  }
2465
+ if (widgetBehavior && typeof widgetBehavior.onBeforeUnmount === 'function') {
2466
+ widgetBehavior.onBeforeUnmount(this, config);
2467
+ }
2909
2468
  },
2910
2469
  template: config.messageTemplate
2911
- }).mount(config.appElementSelector);
2470
+ };
2471
+ var app = Vue.createApp(appDefinition).mount(config.appElementSelector);
2472
+ if (widgetBehavior && typeof widgetBehavior.attach === 'function') {
2473
+ widgetBehavior.attach(app, config);
2474
+ }
2912
2475
  return app;
2913
2476
  };
2914
2477
  return {