@crestapps/ai-chat-ui 1.0.0-preview.8 → 1.0.0-rc.1
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.css +18 -0
- package/dist/ai-chat.css.map +1 -1
- package/dist/ai-chat.js +865 -1047
- package/dist/ai-chat.js.map +1 -1
- package/dist/ai-chat.min.css +1 -1
- package/dist/ai-chat.min.js +1 -1
- package/dist/ai-chat.min.js.map +1 -1
- package/dist/chat-interaction-settings.js +234 -0
- package/dist/chat-interaction-settings.js.map +1 -0
- package/dist/chat-interaction-settings.min.js +2 -0
- package/dist/chat-interaction-settings.min.js.map +1 -0
- package/dist/chat-interaction.js +951 -313
- package/dist/chat-interaction.js.map +1 -1
- package/dist/chat-interaction.min.js +1 -1
- package/dist/chat-interaction.min.js.map +1 -1
- package/dist/chat-widget.css +2 -0
- package/dist/chat-widget.css.map +1 -1
- package/dist/chat-widget.min.css +1 -1
- package/dist/technical-name-generator.js +36 -8
- package/dist/technical-name-generator.js.map +1 -1
- package/dist/technical-name-generator.min.js +1 -1
- package/dist/technical-name-generator.min.js.map +1 -1
- package/package.json +5 -1
- package/README.md +0 -145
package/dist/ai-chat.js
CHANGED
|
@@ -3,15 +3,18 @@
|
|
|
3
3
|
** Any changes made directly to this file will be overwritten next time its asset group is processed by Gulp.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
var _excluded = ["placeholder"];
|
|
6
7
|
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
7
8
|
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
8
9
|
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
9
10
|
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
10
|
-
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
11
11
|
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
12
12
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
13
13
|
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
14
14
|
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
15
|
+
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
16
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
17
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
15
18
|
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
16
19
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
17
20
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
@@ -52,7 +55,7 @@ window.openAIChatManager = function () {
|
|
|
52
55
|
minWidth: 320,
|
|
53
56
|
minHeight: 420
|
|
54
57
|
},
|
|
55
|
-
messageTemplate: "\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <i class=\"fa-regular fa-thumbs-up\"></i>\n </button>\n <button class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <i class=\"fa-regular fa-thumbs-down\"></i>\n </button>\n </span>\n </template>\n <button v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <i :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></i>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message
|
|
58
|
+
messageTemplate: "\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <ol v-if=\"message.citationReferences && message.citationReferences.length\" class=\"ai-chat-citation-list\">\n <li v-for=\"citation in message.citationReferences\" :key=\"'citation-' + (citation.referenceKey || citation.displayIndex)\" class=\"ai-chat-citation-item\">\n <a v-if=\"citation.link\" :href=\"citation.link\" :target=\"citation.isDownload ? null : '_blank'\" :rel=\"citation.isDownload ? null : 'noopener noreferrer'\">{{ citation.label }}</a>\n <span v-else>{{ citation.label }}</span>\n </li>\n </ol>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <i class=\"fa-regular fa-thumbs-up\"></i>\n </button>\n <button class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <i class=\"fa-regular fa-thumbs-down\"></i>\n </button>\n </span>\n </template>\n <button v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <i :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></i>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message)\" :title=\"copyTitle\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <i v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></i>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <i v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></i>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n ",
|
|
56
59
|
indicatorTemplate: "\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><i class=\"fa fa-robot\" style=\"display: inline-block;\"></i></span>\n Assistant\n </div>\n "
|
|
57
60
|
};
|
|
58
61
|
|
|
@@ -72,6 +75,42 @@ window.openAIChatManager = function () {
|
|
|
72
75
|
span.textContent = text;
|
|
73
76
|
return span.innerHTML;
|
|
74
77
|
}
|
|
78
|
+
function containsFontAwesomePlaceholders(root) {
|
|
79
|
+
if (!root || root.nodeType !== 1) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
var selector = 'i[class*="fa-"],i.fa,i.fas,i.far,i.fab';
|
|
83
|
+
if (typeof root.matches === 'function' && root.matches(selector)) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return typeof root.querySelector === 'function' && !!root.querySelector(selector);
|
|
87
|
+
}
|
|
88
|
+
function refreshFontAwesomeIcons(root) {
|
|
89
|
+
var fontAwesome = window.FontAwesome;
|
|
90
|
+
if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
fontAwesome.dom.i2svg({
|
|
94
|
+
node: root
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function observeFontAwesomeIcons(root) {
|
|
98
|
+
if (!root || typeof MutationObserver === 'undefined') {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
var observer = new MutationObserver(function (mutations) {
|
|
102
|
+
mutations.forEach(function (mutation) {
|
|
103
|
+
mutation.addedNodes.forEach(function (node) {
|
|
104
|
+
refreshFontAwesomeIcons(node);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
observer.observe(root, {
|
|
109
|
+
childList: true,
|
|
110
|
+
subtree: true
|
|
111
|
+
});
|
|
112
|
+
return observer;
|
|
113
|
+
}
|
|
75
114
|
function parsePixelValue(value) {
|
|
76
115
|
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
77
116
|
return value;
|
|
@@ -86,16 +125,30 @@ window.openAIChatManager = function () {
|
|
|
86
125
|
return Math.min(Math.max(value, min), max);
|
|
87
126
|
}
|
|
88
127
|
function normalizeReference(reference) {
|
|
89
|
-
var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$link;
|
|
128
|
+
var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$title, _ref4, _normalized$link, _ref5, _normalized$reference;
|
|
90
129
|
if (!reference || _typeof(reference) !== 'object') {
|
|
91
130
|
return null;
|
|
92
131
|
}
|
|
93
132
|
var normalized = Object.assign({}, reference);
|
|
94
133
|
normalized.index = (_ref = (_normalized$index = normalized.index) !== null && _normalized$index !== void 0 ? _normalized$index : normalized.Index) !== null && _ref !== void 0 ? _ref : 0;
|
|
95
134
|
normalized.text = (_ref2 = (_normalized$text = normalized.text) !== null && _normalized$text !== void 0 ? _normalized$text : normalized.Text) !== null && _ref2 !== void 0 ? _ref2 : null;
|
|
96
|
-
normalized.
|
|
135
|
+
normalized.title = (_ref3 = (_normalized$title = normalized.title) !== null && _normalized$title !== void 0 ? _normalized$title : normalized.Title) !== null && _ref3 !== void 0 ? _ref3 : null;
|
|
136
|
+
normalized.link = sanitizeUrl((_ref4 = (_normalized$link = normalized.link) !== null && _normalized$link !== void 0 ? _normalized$link : normalized.Link) !== null && _ref4 !== void 0 ? _ref4 : null);
|
|
137
|
+
normalized.referenceType = (_ref5 = (_normalized$reference = normalized.referenceType) !== null && _normalized$reference !== void 0 ? _normalized$reference : normalized.ReferenceType) !== null && _ref5 !== void 0 ? _ref5 : null;
|
|
97
138
|
return normalized;
|
|
98
139
|
}
|
|
140
|
+
function isDownloadCitationReference(reference) {
|
|
141
|
+
if (!reference || _typeof(reference) !== 'object') {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
if (typeof reference.referenceType === 'string' && reference.referenceType.toLowerCase() === 'document') {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
if (typeof reference.link === 'string' && /\/ai\/documents\/.+\/download(?:$|\?)/i.test(reference.link)) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
99
152
|
function normalizeReferences(references) {
|
|
100
153
|
if (!references || _typeof(references) !== 'object') {
|
|
101
154
|
return {};
|
|
@@ -110,6 +163,125 @@ window.openAIChatManager = function () {
|
|
|
110
163
|
}
|
|
111
164
|
return normalized;
|
|
112
165
|
}
|
|
166
|
+
function getCitationLabel(reference, key) {
|
|
167
|
+
return reference.title || reference.text || key;
|
|
168
|
+
}
|
|
169
|
+
function buildCitationDisplay(content, references) {
|
|
170
|
+
var processedContent = (content || '').trim();
|
|
171
|
+
var messageReferences = normalizeReferences(references);
|
|
172
|
+
if (!processedContent || !Object.keys(messageReferences).length) {
|
|
173
|
+
return {
|
|
174
|
+
content: processedContent,
|
|
175
|
+
citations: []
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
var citedRefs = Object.entries(messageReferences).filter(function (_ref6) {
|
|
179
|
+
var _ref7 = _slicedToArray(_ref6, 1),
|
|
180
|
+
key = _ref7[0];
|
|
181
|
+
return processedContent.includes(key);
|
|
182
|
+
});
|
|
183
|
+
if (!citedRefs.length) {
|
|
184
|
+
return {
|
|
185
|
+
content: processedContent,
|
|
186
|
+
citations: []
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
citedRefs.sort(function (_ref8, _ref9) {
|
|
190
|
+
var _ref0 = _slicedToArray(_ref8, 2),
|
|
191
|
+
a = _ref0[1];
|
|
192
|
+
var _ref1 = _slicedToArray(_ref9, 2),
|
|
193
|
+
b = _ref1[1];
|
|
194
|
+
return a.index - b.index;
|
|
195
|
+
});
|
|
196
|
+
var citations = [];
|
|
197
|
+
var displayIndex = 1;
|
|
198
|
+
var _iterator = _createForOfIteratorHelper(citedRefs),
|
|
199
|
+
_step;
|
|
200
|
+
try {
|
|
201
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
202
|
+
var _step$value = _slicedToArray(_step.value, 2),
|
|
203
|
+
key = _step$value[0],
|
|
204
|
+
value = _step$value[1];
|
|
205
|
+
var placeholder = "__CITE_".concat(displayIndex, "_").concat(value.index || displayIndex, "__");
|
|
206
|
+
processedContent = processedContent.replaceAll(key, placeholder);
|
|
207
|
+
citations.push({
|
|
208
|
+
referenceKey: key,
|
|
209
|
+
displayIndex: displayIndex,
|
|
210
|
+
label: getCitationLabel(value, key),
|
|
211
|
+
link: value.link || null,
|
|
212
|
+
isDownload: isDownloadCitationReference(value),
|
|
213
|
+
placeholder: placeholder
|
|
214
|
+
});
|
|
215
|
+
displayIndex++;
|
|
216
|
+
}
|
|
217
|
+
} catch (err) {
|
|
218
|
+
_iterator.e(err);
|
|
219
|
+
} finally {
|
|
220
|
+
_iterator.f();
|
|
221
|
+
}
|
|
222
|
+
for (var _i2 = 0, _citations = citations; _i2 < _citations.length; _i2++) {
|
|
223
|
+
var citation = _citations[_i2];
|
|
224
|
+
processedContent = processedContent.replaceAll(citation.placeholder, "<sup>".concat(citation.displayIndex, "</sup>"));
|
|
225
|
+
}
|
|
226
|
+
processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');
|
|
227
|
+
return {
|
|
228
|
+
content: processedContent,
|
|
229
|
+
citations: citations.map(function (_ref10) {
|
|
230
|
+
var placeholder = _ref10.placeholder,
|
|
231
|
+
citation = _objectWithoutProperties(_ref10, _excluded);
|
|
232
|
+
return citation;
|
|
233
|
+
})
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function buildCopyContent(content, citations) {
|
|
237
|
+
var copyContent = (content || '').trim();
|
|
238
|
+
if (!copyContent || !Array.isArray(citations) || citations.length === 0) {
|
|
239
|
+
return copyContent;
|
|
240
|
+
}
|
|
241
|
+
var _iterator2 = _createForOfIteratorHelper(citations),
|
|
242
|
+
_step2;
|
|
243
|
+
try {
|
|
244
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
245
|
+
var citation = _step2.value;
|
|
246
|
+
copyContent = copyContent.replaceAll(citation.referenceKey, "[".concat(citation.displayIndex, "]"));
|
|
247
|
+
}
|
|
248
|
+
} catch (err) {
|
|
249
|
+
_iterator2.e(err);
|
|
250
|
+
} finally {
|
|
251
|
+
_iterator2.f();
|
|
252
|
+
}
|
|
253
|
+
copyContent += '\n\nReferences:\n';
|
|
254
|
+
var _iterator3 = _createForOfIteratorHelper(citations),
|
|
255
|
+
_step3;
|
|
256
|
+
try {
|
|
257
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
258
|
+
var _citation = _step3.value;
|
|
259
|
+
copyContent += "".concat(_citation.displayIndex, ". ").concat(_citation.label);
|
|
260
|
+
if (_citation.link) {
|
|
261
|
+
copyContent += " - ".concat(_citation.link);
|
|
262
|
+
}
|
|
263
|
+
copyContent += '\n';
|
|
264
|
+
}
|
|
265
|
+
} catch (err) {
|
|
266
|
+
_iterator3.e(err);
|
|
267
|
+
} finally {
|
|
268
|
+
_iterator3.f();
|
|
269
|
+
}
|
|
270
|
+
return copyContent.trimEnd();
|
|
271
|
+
}
|
|
272
|
+
function updateMessagePresentation(message, references) {
|
|
273
|
+
var messageReferences = normalizeReferences(references !== null && references !== void 0 ? references : message.references);
|
|
274
|
+
var rawContent = typeof message.rawContent === 'string' ? message.rawContent : typeof message.content === 'string' ? message.content : '';
|
|
275
|
+
var citationDisplay = buildCitationDisplay(rawContent, messageReferences);
|
|
276
|
+
message.rawContent = rawContent;
|
|
277
|
+
message.content = rawContent;
|
|
278
|
+
message.displayContent = citationDisplay.content;
|
|
279
|
+
message.references = messageReferences;
|
|
280
|
+
message.citationReferences = citationDisplay.citations;
|
|
281
|
+
message.copyContent = buildCopyContent(rawContent, citationDisplay.citations);
|
|
282
|
+
message.htmlContent = parseMarkdownContent(citationDisplay.content, message);
|
|
283
|
+
return message;
|
|
284
|
+
}
|
|
113
285
|
var renderer = new marked.Renderer();
|
|
114
286
|
|
|
115
287
|
// Modify the link rendering to open in a new tab
|
|
@@ -275,17 +447,17 @@ window.openAIChatManager = function () {
|
|
|
275
447
|
// Defer to requestAnimationFrame so the browser has fully laid out the
|
|
276
448
|
// canvas elements before Chart.js reads their dimensions.
|
|
277
449
|
requestAnimationFrame(function () {
|
|
278
|
-
var
|
|
279
|
-
|
|
450
|
+
var _iterator4 = _createForOfIteratorHelper(charts),
|
|
451
|
+
_step4;
|
|
280
452
|
try {
|
|
281
|
-
for (
|
|
282
|
-
var c =
|
|
453
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
454
|
+
var c = _step4.value;
|
|
283
455
|
renderChartOnCanvas(c.chartId, c.config);
|
|
284
456
|
}
|
|
285
457
|
} catch (err) {
|
|
286
|
-
|
|
458
|
+
_iterator4.e(err);
|
|
287
459
|
} finally {
|
|
288
|
-
|
|
460
|
+
_iterator4.f();
|
|
289
461
|
}
|
|
290
462
|
});
|
|
291
463
|
}
|
|
@@ -338,8 +510,8 @@ window.openAIChatManager = function () {
|
|
|
338
510
|
return;
|
|
339
511
|
}
|
|
340
512
|
requestAnimationFrame(function () {
|
|
341
|
-
for (var
|
|
342
|
-
var chartId = _Object$keys[
|
|
513
|
+
for (var _i3 = 0, _Object$keys = Object.keys(configs); _i3 < _Object$keys.length; _i3++) {
|
|
514
|
+
var chartId = _Object$keys[_i3];
|
|
343
515
|
renderChartOnCanvas(chartId, configs[chartId]);
|
|
344
516
|
}
|
|
345
517
|
});
|
|
@@ -363,6 +535,7 @@ window.openAIChatManager = function () {
|
|
|
363
535
|
var config = Object.assign({}, defaultConfig, instanceConfig);
|
|
364
536
|
config.widget = Object.assign({}, defaultConfig.widget || {}, instanceConfig && instanceConfig.widget ? instanceConfig.widget : {});
|
|
365
537
|
var hasWidgetConfig = !!(instanceConfig && instanceConfig.widget && instanceConfig.widget.chatWidgetContainer && instanceConfig.widget.chatWidgetStateName);
|
|
538
|
+
var widgetBehavior = window.openAIChatWidgetBehavior || null;
|
|
366
539
|
// Keep defaultConfig in sync so renderers use overridden values
|
|
367
540
|
defaultConfig = config;
|
|
368
541
|
if (!config.signalRHubUrl) {
|
|
@@ -385,7 +558,7 @@ window.openAIChatManager = function () {
|
|
|
385
558
|
console.error('The sendButtonElementSelector is required.');
|
|
386
559
|
return;
|
|
387
560
|
}
|
|
388
|
-
var
|
|
561
|
+
var appDefinition = {
|
|
389
562
|
data: function data() {
|
|
390
563
|
return {
|
|
391
564
|
inputElement: null,
|
|
@@ -394,18 +567,6 @@ window.openAIChatManager = function () {
|
|
|
394
567
|
placeholder: null,
|
|
395
568
|
isSessionStarted: false,
|
|
396
569
|
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
570
|
isStreaming: false,
|
|
410
571
|
isNavigatingAway: false,
|
|
411
572
|
autoScroll: true,
|
|
@@ -415,6 +576,8 @@ window.openAIChatManager = function () {
|
|
|
415
576
|
prompt: '',
|
|
416
577
|
documents: config.existingDocuments || [],
|
|
417
578
|
isUploading: false,
|
|
579
|
+
isDocumentOperationPending: false,
|
|
580
|
+
documentOperationQueue: null,
|
|
418
581
|
uploadErrors: [],
|
|
419
582
|
isDragOver: false,
|
|
420
583
|
documentBar: null,
|
|
@@ -444,7 +607,11 @@ window.openAIChatManager = function () {
|
|
|
444
607
|
conversationModeEnabled: config.chatMode === 'Conversation',
|
|
445
608
|
conversationButton: null,
|
|
446
609
|
isConversationMode: false,
|
|
447
|
-
notificationDismissTimers: {}
|
|
610
|
+
notificationDismissTimers: {},
|
|
611
|
+
pendingSessionPromise: null,
|
|
612
|
+
pendingSessionResolver: null,
|
|
613
|
+
pendingSessionRejector: null,
|
|
614
|
+
pendingSessionTimeoutId: null
|
|
448
615
|
};
|
|
449
616
|
},
|
|
450
617
|
computed: {
|
|
@@ -461,336 +628,6 @@ window.openAIChatManager = function () {
|
|
|
461
628
|
handleBeforeUnload: function handleBeforeUnload() {
|
|
462
629
|
this.isNavigatingAway = true;
|
|
463
630
|
},
|
|
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
631
|
handleDragOver: function handleDragOver(e) {
|
|
795
632
|
if (!config.sessionDocumentsEnabled) return;
|
|
796
633
|
e.preventDefault();
|
|
@@ -815,180 +652,272 @@ window.openAIChatManager = function () {
|
|
|
815
652
|
var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;
|
|
816
653
|
if (inputArea) inputArea.classList.remove('ai-chat-drag-over');
|
|
817
654
|
if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
|
818
|
-
this.uploadFiles(e.dataTransfer.files);
|
|
655
|
+
this.uploadFiles(Array.from(e.dataTransfer.files));
|
|
819
656
|
}
|
|
820
657
|
},
|
|
821
658
|
triggerFileInput: function triggerFileInput() {
|
|
822
|
-
if (!config.sessionDocumentsEnabled) return;
|
|
659
|
+
if (!config.sessionDocumentsEnabled || this.isDocumentOperationPending) return;
|
|
823
660
|
var fileInput = document.getElementById('ai-chat-doc-input');
|
|
824
661
|
if (fileInput) fileInput.click();
|
|
825
662
|
},
|
|
826
663
|
handleFileInputChange: function handleFileInputChange(e) {
|
|
827
|
-
var files = e.target.files;
|
|
664
|
+
var files = e.target.files ? Array.from(e.target.files) : [];
|
|
828
665
|
if (files && files.length > 0) {
|
|
829
666
|
this.uploadFiles(files);
|
|
830
667
|
}
|
|
831
668
|
e.target.value = '';
|
|
832
669
|
},
|
|
833
|
-
|
|
834
|
-
var
|
|
835
|
-
|
|
836
|
-
|
|
670
|
+
queueDocumentOperation: function queueDocumentOperation(operation) {
|
|
671
|
+
var self = this;
|
|
672
|
+
var previousOperation = this.documentOperationQueue || Promise.resolve();
|
|
673
|
+
var nextOperation = previousOperation["catch"](function () {}).then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
|
|
837
674
|
return _regenerator().w(function (_context) {
|
|
838
675
|
while (1) switch (_context.p = _context.n) {
|
|
676
|
+
case 0:
|
|
677
|
+
self.isDocumentOperationPending = true;
|
|
678
|
+
_context.p = 1;
|
|
679
|
+
_context.n = 2;
|
|
680
|
+
return operation();
|
|
681
|
+
case 2:
|
|
682
|
+
return _context.a(2, _context.v);
|
|
683
|
+
case 3:
|
|
684
|
+
_context.p = 3;
|
|
685
|
+
self.isDocumentOperationPending = false;
|
|
686
|
+
return _context.f(3);
|
|
687
|
+
case 4:
|
|
688
|
+
return _context.a(2);
|
|
689
|
+
}
|
|
690
|
+
}, _callee, null, [[1,, 3, 4]]);
|
|
691
|
+
})));
|
|
692
|
+
this.documentOperationQueue = nextOperation["finally"](function () {
|
|
693
|
+
if (self.documentOperationQueue === nextOperation) {
|
|
694
|
+
self.documentOperationQueue = null;
|
|
695
|
+
}
|
|
696
|
+
});
|
|
697
|
+
return this.documentOperationQueue;
|
|
698
|
+
},
|
|
699
|
+
uploadFiles: function uploadFiles(files) {
|
|
700
|
+
var _this = this;
|
|
701
|
+
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
|
|
702
|
+
var filesToUpload;
|
|
703
|
+
return _regenerator().w(function (_context3) {
|
|
704
|
+
while (1) switch (_context3.n) {
|
|
839
705
|
case 0:
|
|
840
706
|
if (config.uploadDocumentUrl) {
|
|
841
|
-
|
|
707
|
+
_context3.n = 1;
|
|
842
708
|
break;
|
|
843
709
|
}
|
|
844
|
-
return
|
|
710
|
+
return _context3.a(2);
|
|
845
711
|
case 1:
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
_context.n = 2;
|
|
712
|
+
filesToUpload = Array.isArray(files) ? files.slice() : Array.from(files || []);
|
|
713
|
+
if (!(filesToUpload.length === 0)) {
|
|
714
|
+
_context3.n = 2;
|
|
850
715
|
break;
|
|
851
716
|
}
|
|
852
|
-
|
|
853
|
-
return _context.a(2);
|
|
717
|
+
return _context3.a(2);
|
|
854
718
|
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
|
-
|
|
719
|
+
return _context3.a(2, _this.queueDocumentOperation(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
720
|
+
var sessionId, profileId, formData, i, response, errorText, uploadError, result, _t, _t2;
|
|
721
|
+
return _regenerator().w(function (_context2) {
|
|
722
|
+
while (1) switch (_context2.p = _context2.n) {
|
|
723
|
+
case 0:
|
|
724
|
+
sessionId = _this.getSessionId();
|
|
725
|
+
profileId = _this.getProfileId();
|
|
726
|
+
if (sessionId) {
|
|
727
|
+
_context2.n = 4;
|
|
728
|
+
break;
|
|
729
|
+
}
|
|
730
|
+
_context2.p = 1;
|
|
731
|
+
_context2.n = 2;
|
|
732
|
+
return _this.ensureSessionForDocuments(profileId);
|
|
733
|
+
case 2:
|
|
734
|
+
sessionId = _context2.v;
|
|
735
|
+
_context2.n = 4;
|
|
736
|
+
break;
|
|
737
|
+
case 3:
|
|
738
|
+
_context2.p = 3;
|
|
739
|
+
_t = _context2.v;
|
|
740
|
+
console.error('Failed to create a chat session for document upload:', _t);
|
|
741
|
+
_this.uploadErrors = [{
|
|
742
|
+
fileName: '',
|
|
743
|
+
error: 'Could not create a chat session for the upload.'
|
|
744
|
+
}];
|
|
745
|
+
_this.renderDocumentBar();
|
|
746
|
+
return _context2.a(2);
|
|
747
|
+
case 4:
|
|
748
|
+
if (sessionId) {
|
|
749
|
+
_context2.n = 5;
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
console.warn('Cannot upload documents without a session or profile.');
|
|
753
|
+
_this.uploadErrors = [{
|
|
754
|
+
fileName: '',
|
|
755
|
+
error: 'Could not create a chat session for the upload.'
|
|
756
|
+
}];
|
|
757
|
+
_this.renderDocumentBar();
|
|
758
|
+
return _context2.a(2);
|
|
759
|
+
case 5:
|
|
760
|
+
_this.isUploading = true;
|
|
761
|
+
_this.uploadErrors = [];
|
|
762
|
+
_this.renderDocumentBar();
|
|
763
|
+
_context2.p = 6;
|
|
764
|
+
formData = new FormData();
|
|
765
|
+
formData.append('sessionId', sessionId);
|
|
766
|
+
for (i = 0; i < filesToUpload.length; i++) {
|
|
767
|
+
formData.append('files', filesToUpload[i]);
|
|
768
|
+
}
|
|
769
|
+
_context2.n = 7;
|
|
770
|
+
return fetch(config.uploadDocumentUrl, {
|
|
771
|
+
method: 'POST',
|
|
772
|
+
body: formData
|
|
773
|
+
});
|
|
774
|
+
case 7:
|
|
775
|
+
response = _context2.v;
|
|
776
|
+
if (response.ok) {
|
|
777
|
+
_context2.n = 9;
|
|
778
|
+
break;
|
|
779
|
+
}
|
|
780
|
+
_context2.n = 8;
|
|
781
|
+
return response.text();
|
|
782
|
+
case 8:
|
|
783
|
+
errorText = _context2.v;
|
|
784
|
+
uploadError = _this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');
|
|
785
|
+
console.error('Upload failed:', errorText);
|
|
786
|
+
_this.uploadErrors = [{
|
|
787
|
+
fileName: '',
|
|
788
|
+
error: uploadError
|
|
789
|
+
}];
|
|
790
|
+
return _context2.a(2);
|
|
791
|
+
case 9:
|
|
792
|
+
_context2.n = 10;
|
|
793
|
+
return response.json();
|
|
794
|
+
case 10:
|
|
795
|
+
result = _context2.v;
|
|
796
|
+
if (result.sessionId && result.sessionId !== _this.getSessionId()) {
|
|
797
|
+
_this.initializeSession(result.sessionId);
|
|
798
|
+
}
|
|
799
|
+
if (Array.isArray(result.documents)) {
|
|
800
|
+
_this.documents = result.documents;
|
|
801
|
+
} else if (result.uploaded && result.uploaded.length > 0) {
|
|
802
|
+
_this.documents = _this.documents.concat(result.uploaded);
|
|
803
|
+
}
|
|
804
|
+
if (result.failed && result.failed.length > 0) {
|
|
805
|
+
_this.uploadErrors = result.failed;
|
|
806
|
+
}
|
|
807
|
+
_context2.n = 12;
|
|
808
|
+
break;
|
|
809
|
+
case 11:
|
|
810
|
+
_context2.p = 11;
|
|
811
|
+
_t2 = _context2.v;
|
|
812
|
+
console.error('Upload error:', _t2);
|
|
813
|
+
_this.uploadErrors = [{
|
|
814
|
+
fileName: '',
|
|
815
|
+
error: 'Upload failed. Please try again.'
|
|
816
|
+
}];
|
|
817
|
+
if (_this.getSessionId()) {
|
|
818
|
+
_this.reloadCurrentSession();
|
|
819
|
+
}
|
|
820
|
+
case 12:
|
|
821
|
+
_context2.p = 12;
|
|
822
|
+
_this.isUploading = false;
|
|
823
|
+
_this.renderDocumentBar();
|
|
824
|
+
return _context2.f(12);
|
|
825
|
+
case 13:
|
|
826
|
+
return _context2.a(2);
|
|
827
|
+
}
|
|
828
|
+
}, _callee2, null, [[6, 11, 12, 13], [1, 3]]);
|
|
829
|
+
}))));
|
|
924
830
|
}
|
|
925
|
-
},
|
|
831
|
+
}, _callee3);
|
|
926
832
|
}))();
|
|
927
833
|
},
|
|
928
834
|
removeDocument: function removeDocument(doc) {
|
|
929
|
-
var
|
|
930
|
-
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
while (1) switch (_context2.p = _context2.n) {
|
|
835
|
+
var _this2 = this;
|
|
836
|
+
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
|
|
837
|
+
return _regenerator().w(function (_context5) {
|
|
838
|
+
while (1) switch (_context5.n) {
|
|
934
839
|
case 0:
|
|
935
840
|
if (config.removeDocumentUrl) {
|
|
936
|
-
|
|
841
|
+
_context5.n = 1;
|
|
937
842
|
break;
|
|
938
843
|
}
|
|
939
|
-
return
|
|
844
|
+
return _context5.a(2);
|
|
940
845
|
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
|
-
|
|
846
|
+
return _context5.a(2, _this2.queueDocumentOperation(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
847
|
+
var sessionId, response, result, idx, errorText, removeError, _t3;
|
|
848
|
+
return _regenerator().w(function (_context4) {
|
|
849
|
+
while (1) switch (_context4.p = _context4.n) {
|
|
850
|
+
case 0:
|
|
851
|
+
_context4.p = 0;
|
|
852
|
+
sessionId = _this2.getSessionId();
|
|
853
|
+
_context4.n = 1;
|
|
854
|
+
return fetch(config.removeDocumentUrl, {
|
|
855
|
+
method: 'POST',
|
|
856
|
+
headers: {
|
|
857
|
+
'Content-Type': 'application/json'
|
|
858
|
+
},
|
|
859
|
+
body: JSON.stringify({
|
|
860
|
+
itemId: sessionId,
|
|
861
|
+
documentId: doc.documentId
|
|
862
|
+
})
|
|
863
|
+
});
|
|
864
|
+
case 1:
|
|
865
|
+
response = _context4.v;
|
|
866
|
+
if (!response.ok) {
|
|
867
|
+
_context4.n = 3;
|
|
868
|
+
break;
|
|
869
|
+
}
|
|
870
|
+
_context4.n = 2;
|
|
871
|
+
return response.json();
|
|
872
|
+
case 2:
|
|
873
|
+
result = _context4.v;
|
|
874
|
+
if (Array.isArray(result.documents)) {
|
|
875
|
+
_this2.documents = result.documents;
|
|
876
|
+
} else {
|
|
877
|
+
idx = _this2.documents.indexOf(doc);
|
|
878
|
+
if (idx > -1) {
|
|
879
|
+
_this2.documents.splice(idx, 1);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
_context4.n = 5;
|
|
883
|
+
break;
|
|
884
|
+
case 3:
|
|
885
|
+
_context4.n = 4;
|
|
886
|
+
return response.text();
|
|
887
|
+
case 4:
|
|
888
|
+
errorText = _context4.v;
|
|
889
|
+
removeError = _this2.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');
|
|
890
|
+
console.error('Failed to remove document:', response.status, errorText);
|
|
891
|
+
_this2.uploadErrors = [{
|
|
892
|
+
fileName: doc.fileName || '',
|
|
893
|
+
error: removeError
|
|
894
|
+
}];
|
|
895
|
+
if (sessionId) {
|
|
896
|
+
_this2.reloadCurrentSession();
|
|
897
|
+
}
|
|
898
|
+
_this2.renderDocumentBar();
|
|
899
|
+
case 5:
|
|
900
|
+
_context4.n = 7;
|
|
901
|
+
break;
|
|
902
|
+
case 6:
|
|
903
|
+
_context4.p = 6;
|
|
904
|
+
_t3 = _context4.v;
|
|
905
|
+
console.error('Remove document error:', _t3);
|
|
906
|
+
_this2.uploadErrors = [{
|
|
907
|
+
fileName: doc.fileName || '',
|
|
908
|
+
error: 'Failed to remove document. Please try again.'
|
|
909
|
+
}];
|
|
910
|
+
if (_this2.getSessionId()) {
|
|
911
|
+
_this2.reloadCurrentSession();
|
|
912
|
+
}
|
|
913
|
+
_this2.renderDocumentBar();
|
|
914
|
+
case 7:
|
|
915
|
+
return _context4.a(2);
|
|
916
|
+
}
|
|
917
|
+
}, _callee4, null, [[0, 6]]);
|
|
918
|
+
}))));
|
|
990
919
|
}
|
|
991
|
-
},
|
|
920
|
+
}, _callee5);
|
|
992
921
|
}))();
|
|
993
922
|
},
|
|
994
923
|
formatFileSize: function formatFileSize(bytes) {
|
|
@@ -1012,7 +941,7 @@ window.openAIChatManager = function () {
|
|
|
1012
941
|
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
942
|
html += '<i class="fa-solid fa-file-lines" style="font-size: 0.7rem;"></i> ';
|
|
1014
943
|
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>';
|
|
944
|
+
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
945
|
html += '</span>';
|
|
1017
946
|
}
|
|
1018
947
|
for (var m = 0; m < this.uploadErrors.length; m++) {
|
|
@@ -1031,7 +960,7 @@ window.openAIChatManager = function () {
|
|
|
1031
960
|
html += '<span class="spinner-border spinner-border-sm" style="width: 0.7rem; height: 0.7rem;"></span> Uploading...';
|
|
1032
961
|
html += '</span>';
|
|
1033
962
|
}
|
|
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">';
|
|
963
|
+
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
964
|
html += '<i class="fa-solid fa-paperclip"></i>';
|
|
1036
965
|
if (this.documents.length === 0 && !this.isUploading) {
|
|
1037
966
|
html += ' <span>Attach files</span>';
|
|
@@ -1054,6 +983,9 @@ window.openAIChatManager = function () {
|
|
|
1054
983
|
return function (e) {
|
|
1055
984
|
e.preventDefault();
|
|
1056
985
|
e.stopPropagation();
|
|
986
|
+
if (self.isDocumentOperationPending) {
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
1057
989
|
var docToRemove = self.documents[idx];
|
|
1058
990
|
if (docToRemove) self.removeDocument(docToRemove);
|
|
1059
991
|
};
|
|
@@ -1078,6 +1010,9 @@ window.openAIChatManager = function () {
|
|
|
1078
1010
|
if (addBtn) {
|
|
1079
1011
|
addBtn.addEventListener('click', function (e) {
|
|
1080
1012
|
e.preventDefault();
|
|
1013
|
+
if (self.isDocumentOperationPending) {
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1081
1016
|
self.triggerFileInput();
|
|
1082
1017
|
});
|
|
1083
1018
|
}
|
|
@@ -1154,139 +1089,135 @@ window.openAIChatManager = function () {
|
|
|
1154
1089
|
return !!message && message.isStreaming && index === this.lastAssistantIndex && !(appearance && appearance.disableStreamingAnimation);
|
|
1155
1090
|
},
|
|
1156
1091
|
startConnection: function startConnection() {
|
|
1157
|
-
var
|
|
1158
|
-
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
1159
|
-
var
|
|
1160
|
-
return _regenerator().w(function (
|
|
1161
|
-
while (1) switch (
|
|
1092
|
+
var _this3 = this;
|
|
1093
|
+
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
|
|
1094
|
+
var _t4;
|
|
1095
|
+
return _regenerator().w(function (_context6) {
|
|
1096
|
+
while (1) switch (_context6.p = _context6.n) {
|
|
1162
1097
|
case 0:
|
|
1163
|
-
|
|
1098
|
+
_this3.connection = new signalR.HubConnectionBuilder().withUrl(config.signalRHubUrl).withAutomaticReconnect().build();
|
|
1164
1099
|
|
|
1165
1100
|
// Allow long-running operations (e.g., multi-step MCP tool calls)
|
|
1166
1101
|
// without the client disconnecting prematurely.
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1102
|
+
_this3.connection.serverTimeoutInMilliseconds = 600000;
|
|
1103
|
+
_this3.connection.keepAliveIntervalInMilliseconds = 15000;
|
|
1104
|
+
_this3.connection.on("LoadSession", function (data) {
|
|
1170
1105
|
var _data$messages;
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1106
|
+
_this3.initializeSession(data.sessionId, true);
|
|
1107
|
+
_this3.messages = [];
|
|
1108
|
+
_this3.documents = data.documents || [];
|
|
1109
|
+
_this3.uploadErrors = [];
|
|
1174
1110
|
((_data$messages = data.messages) !== null && _data$messages !== void 0 ? _data$messages : []).forEach(function (msg) {
|
|
1175
|
-
|
|
1176
|
-
|
|
1111
|
+
_this3.addMessage(msg);
|
|
1112
|
+
_this3.$nextTick(function () {
|
|
1177
1113
|
renderChartsInMessage(msg);
|
|
1178
1114
|
});
|
|
1179
1115
|
});
|
|
1180
1116
|
|
|
1181
1117
|
// Update feedback icons in the DOM after all messages have rendered.
|
|
1182
|
-
|
|
1183
|
-
|
|
1118
|
+
_this3.$nextTick(function () {
|
|
1119
|
+
_this3.refreshAllFeedbackIcons();
|
|
1184
1120
|
});
|
|
1185
1121
|
|
|
1186
1122
|
// When the session is new (no messages) and an initial prompt is configured,
|
|
1187
1123
|
// automatically send it as the first user message to trigger an AI response.
|
|
1188
|
-
if (
|
|
1189
|
-
|
|
1190
|
-
|
|
1124
|
+
if (_this3.messages.length === 0 && config.initialPrompt) {
|
|
1125
|
+
_this3.prompt = config.initialPrompt;
|
|
1126
|
+
_this3.sendMessage();
|
|
1191
1127
|
}
|
|
1192
1128
|
});
|
|
1193
|
-
|
|
1129
|
+
_this3.connection.on("ReceiveError", function (error) {
|
|
1194
1130
|
console.error("SignalR Error: ", error);
|
|
1195
|
-
if (
|
|
1196
|
-
|
|
1131
|
+
if (_this3.isRecording) {
|
|
1132
|
+
_this3.stopRecording();
|
|
1197
1133
|
}
|
|
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();
|
|
1134
|
+
if (widgetBehavior && typeof widgetBehavior.handleReceiveError === 'function') {
|
|
1135
|
+
widgetBehavior.handleReceiveError(_this3, error, config);
|
|
1205
1136
|
}
|
|
1206
1137
|
});
|
|
1207
|
-
|
|
1208
|
-
var msg =
|
|
1138
|
+
_this3.connection.on("MessageRated", function (messageId, userRating) {
|
|
1139
|
+
var msg = _this3.messages.find(function (m) {
|
|
1209
1140
|
return m.id === messageId;
|
|
1210
1141
|
});
|
|
1211
1142
|
if (msg) {
|
|
1212
1143
|
msg.userRating = userRating;
|
|
1213
1144
|
}
|
|
1214
1145
|
});
|
|
1215
|
-
|
|
1216
|
-
if (
|
|
1146
|
+
_this3.connection.on("ReceiveTranscript", function (sessionId, text, isFinal) {
|
|
1147
|
+
if (_this3.isConversationMode) {
|
|
1217
1148
|
if (!isFinal && text) {
|
|
1218
|
-
|
|
1149
|
+
_this3._conversationPartialTranscript = text;
|
|
1219
1150
|
var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
1220
1151
|
var html = '<p class="ai-partial-transcript">' + escaped + '</p>';
|
|
1221
1152
|
|
|
1222
1153
|
// Show partial transcript as a live user message.
|
|
1223
|
-
if (!
|
|
1224
|
-
|
|
1225
|
-
|
|
1154
|
+
if (!_this3._conversationPartialMessage) {
|
|
1155
|
+
_this3.hidePlaceholder();
|
|
1156
|
+
_this3._conversationPartialMessage = {
|
|
1226
1157
|
role: 'user',
|
|
1227
1158
|
content: text,
|
|
1228
1159
|
htmlContent: html,
|
|
1229
1160
|
isPartial: true
|
|
1230
1161
|
};
|
|
1231
|
-
|
|
1162
|
+
_this3.messages.push(_this3._conversationPartialMessage);
|
|
1232
1163
|
} else {
|
|
1233
|
-
|
|
1234
|
-
|
|
1164
|
+
_this3._conversationPartialMessage.content = text;
|
|
1165
|
+
_this3._conversationPartialMessage.htmlContent = html;
|
|
1235
1166
|
}
|
|
1236
|
-
|
|
1167
|
+
_this3.scrollToBottom();
|
|
1237
1168
|
}
|
|
1238
1169
|
return;
|
|
1239
1170
|
}
|
|
1240
|
-
if (text && !
|
|
1241
|
-
|
|
1242
|
-
if (
|
|
1243
|
-
|
|
1244
|
-
|
|
1171
|
+
if (text && !_this3._audioInputSent) {
|
|
1172
|
+
_this3.prompt = _this3.preRecordingPrompt + text;
|
|
1173
|
+
if (_this3.inputElement) {
|
|
1174
|
+
_this3.inputElement.value = _this3.prompt;
|
|
1175
|
+
_this3.inputElement.dispatchEvent(new Event('input'));
|
|
1245
1176
|
}
|
|
1246
1177
|
}
|
|
1247
1178
|
});
|
|
1248
|
-
|
|
1179
|
+
_this3.connection.on("ReceiveConversationUserMessage", function (sessionId, text) {
|
|
1249
1180
|
if (text) {
|
|
1250
|
-
|
|
1181
|
+
_this3.stopAudio();
|
|
1251
1182
|
|
|
1252
1183
|
// If there's an interrupted assistant message still streaming,
|
|
1253
1184
|
// mark it as done to stop the spinner animation.
|
|
1254
|
-
if (
|
|
1255
|
-
var oldMsg =
|
|
1185
|
+
if (_this3._conversationAssistantMessage) {
|
|
1186
|
+
var oldMsg = _this3.messages[_this3._conversationAssistantMessage.index];
|
|
1256
1187
|
if (oldMsg) {
|
|
1257
1188
|
oldMsg.isStreaming = false;
|
|
1258
1189
|
}
|
|
1259
|
-
|
|
1190
|
+
_this3._conversationAssistantMessage = null;
|
|
1260
1191
|
}
|
|
1261
1192
|
|
|
1262
1193
|
// Replace the partial transcript message with the final one.
|
|
1263
|
-
if (
|
|
1194
|
+
if (_this3._conversationPartialMessage) {
|
|
1264
1195
|
var escaped = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1196
|
+
_this3._conversationPartialMessage.content = text;
|
|
1197
|
+
_this3._conversationPartialMessage.htmlContent = '<p>' + escaped + '</p>';
|
|
1198
|
+
_this3._conversationPartialMessage.isPartial = false;
|
|
1199
|
+
_this3._conversationPartialMessage = null;
|
|
1269
1200
|
} else {
|
|
1270
|
-
|
|
1201
|
+
_this3.addMessage({
|
|
1271
1202
|
role: 'user',
|
|
1272
1203
|
content: text
|
|
1273
1204
|
});
|
|
1274
1205
|
}
|
|
1275
|
-
|
|
1206
|
+
_this3.scrollToBottom();
|
|
1276
1207
|
}
|
|
1277
1208
|
});
|
|
1278
|
-
|
|
1279
|
-
if (!
|
|
1280
|
-
|
|
1281
|
-
|
|
1209
|
+
_this3.connection.on("ReceiveConversationAssistantToken", function (sessionId, messageId, token, responseId, references, appearance) {
|
|
1210
|
+
if (!_this3._conversationAssistantMessage) {
|
|
1211
|
+
_this3.stopAudio();
|
|
1212
|
+
_this3.hideTypingIndicator();
|
|
1282
1213
|
|
|
1283
1214
|
// Ensure no stale streaming indicators remain from prior messages.
|
|
1284
|
-
for (var j = 0; j <
|
|
1285
|
-
if (
|
|
1286
|
-
|
|
1215
|
+
for (var j = 0; j < _this3.messages.length; j++) {
|
|
1216
|
+
if (_this3.messages[j].isStreaming) {
|
|
1217
|
+
_this3.messages[j].isStreaming = false;
|
|
1287
1218
|
}
|
|
1288
1219
|
}
|
|
1289
|
-
var msgIndex =
|
|
1220
|
+
var msgIndex = _this3.messages.length;
|
|
1290
1221
|
var newMessage = {
|
|
1291
1222
|
id: messageId,
|
|
1292
1223
|
role: "assistant",
|
|
@@ -1294,96 +1225,100 @@ window.openAIChatManager = function () {
|
|
|
1294
1225
|
htmlContent: "",
|
|
1295
1226
|
isStreaming: true,
|
|
1296
1227
|
userRating: null,
|
|
1297
|
-
appearance:
|
|
1228
|
+
appearance: _this3.normalizeAssistantAppearance(appearance),
|
|
1229
|
+
references: {}
|
|
1298
1230
|
};
|
|
1299
|
-
|
|
1300
|
-
|
|
1231
|
+
_this3.messages.push(newMessage);
|
|
1232
|
+
_this3._conversationAssistantMessage = {
|
|
1301
1233
|
index: msgIndex,
|
|
1302
1234
|
content: ''
|
|
1303
1235
|
};
|
|
1304
1236
|
}
|
|
1305
|
-
|
|
1306
|
-
var msg =
|
|
1237
|
+
_this3._conversationAssistantMessage.content += token;
|
|
1238
|
+
var msg = _this3.messages[_this3._conversationAssistantMessage.index];
|
|
1307
1239
|
if (msg) {
|
|
1308
1240
|
if (!msg.appearance) {
|
|
1309
|
-
msg.appearance =
|
|
1241
|
+
msg.appearance = _this3.normalizeAssistantAppearance(appearance);
|
|
1310
1242
|
}
|
|
1311
|
-
msg.
|
|
1312
|
-
msg.
|
|
1313
|
-
|
|
1243
|
+
msg.rawContent = _this3._conversationAssistantMessage.content;
|
|
1244
|
+
msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));
|
|
1245
|
+
updateMessagePresentation(msg, msg.references);
|
|
1246
|
+
_this3.$nextTick(function () {
|
|
1314
1247
|
renderChartsInMessage(msg);
|
|
1315
|
-
|
|
1248
|
+
_this3.scrollToBottom();
|
|
1316
1249
|
});
|
|
1317
1250
|
}
|
|
1318
1251
|
});
|
|
1319
|
-
|
|
1320
|
-
if (
|
|
1321
|
-
var msg =
|
|
1252
|
+
_this3.connection.on("ReceiveConversationAssistantComplete", function (sessionId, messageId, references) {
|
|
1253
|
+
if (_this3._conversationAssistantMessage) {
|
|
1254
|
+
var msg = _this3.messages[_this3._conversationAssistantMessage.index];
|
|
1322
1255
|
if (msg) {
|
|
1323
1256
|
msg.isStreaming = false;
|
|
1257
|
+
msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));
|
|
1258
|
+
updateMessagePresentation(msg, msg.references);
|
|
1324
1259
|
}
|
|
1325
|
-
|
|
1260
|
+
_this3._conversationAssistantMessage = null;
|
|
1326
1261
|
}
|
|
1327
1262
|
});
|
|
1328
|
-
|
|
1263
|
+
_this3.connection.on("ReceiveAudioChunk", function (sessionId, base64Audio, contentType) {
|
|
1329
1264
|
if (base64Audio) {
|
|
1330
1265
|
var binaryString = atob(base64Audio);
|
|
1331
1266
|
var bytes = new Uint8Array(binaryString.length);
|
|
1332
1267
|
for (var i = 0; i < binaryString.length; i++) {
|
|
1333
1268
|
bytes[i] = binaryString.charCodeAt(i);
|
|
1334
1269
|
}
|
|
1335
|
-
|
|
1270
|
+
_this3.audioChunks.push(bytes);
|
|
1336
1271
|
}
|
|
1337
1272
|
});
|
|
1338
|
-
|
|
1339
|
-
|
|
1273
|
+
_this3.connection.on("ReceiveAudioComplete", function (sessionId) {
|
|
1274
|
+
_this3.playCollectedAudio();
|
|
1340
1275
|
});
|
|
1341
|
-
|
|
1342
|
-
|
|
1276
|
+
_this3.connection.on("ReceiveNotification", function (notification) {
|
|
1277
|
+
_this3.receiveNotification(notification);
|
|
1343
1278
|
});
|
|
1344
|
-
|
|
1345
|
-
|
|
1279
|
+
_this3.connection.on("UpdateNotification", function (notification) {
|
|
1280
|
+
_this3.updateNotification(notification);
|
|
1346
1281
|
});
|
|
1347
|
-
|
|
1348
|
-
|
|
1282
|
+
_this3.connection.on("RemoveNotification", function (notificationType) {
|
|
1283
|
+
_this3.removeNotification(notificationType);
|
|
1349
1284
|
});
|
|
1350
|
-
|
|
1285
|
+
_this3.connection.onreconnecting(function () {
|
|
1351
1286
|
console.warn("SignalR: reconnecting...");
|
|
1352
1287
|
});
|
|
1353
|
-
|
|
1288
|
+
_this3.connection.onreconnected(function () {
|
|
1354
1289
|
console.info("SignalR: reconnected.");
|
|
1355
|
-
if (
|
|
1356
|
-
|
|
1290
|
+
if (_this3.isSessionStarted) {
|
|
1291
|
+
_this3.reloadCurrentSession();
|
|
1357
1292
|
} else if (config.autoCreateSession) {
|
|
1358
|
-
|
|
1293
|
+
_this3.startNewSession();
|
|
1359
1294
|
}
|
|
1360
1295
|
});
|
|
1361
|
-
|
|
1362
|
-
if (
|
|
1296
|
+
_this3.connection.onclose(function (error) {
|
|
1297
|
+
if (_this3.isNavigatingAway) {
|
|
1363
1298
|
return;
|
|
1364
1299
|
}
|
|
1365
1300
|
if (error) {
|
|
1366
1301
|
console.warn("SignalR connection closed with error:", error.message || error);
|
|
1367
1302
|
}
|
|
1368
1303
|
});
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
return
|
|
1304
|
+
_context6.p = 1;
|
|
1305
|
+
_context6.n = 2;
|
|
1306
|
+
return _this3.connection.start();
|
|
1372
1307
|
case 2:
|
|
1373
|
-
|
|
1308
|
+
_context6.n = 4;
|
|
1374
1309
|
break;
|
|
1375
1310
|
case 3:
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
console.error("SignalR Connection Error: ",
|
|
1311
|
+
_context6.p = 3;
|
|
1312
|
+
_t4 = _context6.v;
|
|
1313
|
+
console.error("SignalR Connection Error: ", _t4);
|
|
1379
1314
|
case 4:
|
|
1380
|
-
return
|
|
1315
|
+
return _context6.a(2);
|
|
1381
1316
|
}
|
|
1382
|
-
},
|
|
1317
|
+
}, _callee6, null, [[1, 3]]);
|
|
1383
1318
|
}))();
|
|
1384
1319
|
},
|
|
1385
1320
|
addMessageInternal: function addMessageInternal(message) {
|
|
1386
|
-
var
|
|
1321
|
+
var _this4 = this;
|
|
1387
1322
|
if (message.role === 'assistant') {
|
|
1388
1323
|
message.appearance = this.normalizeAssistantAppearance(message.appearance);
|
|
1389
1324
|
}
|
|
@@ -1397,7 +1332,7 @@ window.openAIChatManager = function () {
|
|
|
1397
1332
|
}));
|
|
1398
1333
|
this.messages.push(message);
|
|
1399
1334
|
this.$nextTick(function () {
|
|
1400
|
-
|
|
1335
|
+
_this4.fireEvent(new CustomEvent("addedOpenAIPromotMessage", {
|
|
1401
1336
|
detail: {
|
|
1402
1337
|
message: message
|
|
1403
1338
|
}
|
|
@@ -1405,105 +1340,32 @@ window.openAIChatManager = function () {
|
|
|
1405
1340
|
});
|
|
1406
1341
|
},
|
|
1407
1342
|
addMessage: function addMessage(message) {
|
|
1408
|
-
var
|
|
1343
|
+
var _this5 = this;
|
|
1409
1344
|
// Ensure userRating is always defined for Vue reactivity.
|
|
1410
1345
|
if (message.userRating === undefined) {
|
|
1411
1346
|
message.userRating = null;
|
|
1412
1347
|
}
|
|
1413
1348
|
if (message.content) {
|
|
1414
|
-
var
|
|
1415
|
-
message.
|
|
1416
|
-
|
|
1417
|
-
// Only include references that were actually cited in the response.
|
|
1418
|
-
var citedRefs = Object.entries(message.references).filter(function (_ref4) {
|
|
1419
|
-
var _ref5 = _slicedToArray(_ref4, 1),
|
|
1420
|
-
key = _ref5[0];
|
|
1421
|
-
return processedContent.includes(key);
|
|
1422
|
-
});
|
|
1423
|
-
if (citedRefs.length) {
|
|
1424
|
-
// Sort by original index so display indices follow a natural order.
|
|
1425
|
-
citedRefs.sort(function (_ref6, _ref7) {
|
|
1426
|
-
var _ref8 = _slicedToArray(_ref6, 2),
|
|
1427
|
-
a = _ref8[1];
|
|
1428
|
-
var _ref9 = _slicedToArray(_ref7, 2),
|
|
1429
|
-
b = _ref9[1];
|
|
1430
|
-
return a.index - b.index;
|
|
1431
|
-
});
|
|
1432
|
-
|
|
1433
|
-
// Phase 1: Replace all markers with unique placeholders.
|
|
1434
|
-
var displayIndex = 1;
|
|
1435
|
-
var _iterator2 = _createForOfIteratorHelper(citedRefs),
|
|
1436
|
-
_step2;
|
|
1437
|
-
try {
|
|
1438
|
-
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
1439
|
-
var _step2$value = _slicedToArray(_step2.value, 2),
|
|
1440
|
-
key = _step2$value[0],
|
|
1441
|
-
value = _step2$value[1];
|
|
1442
|
-
var placeholder = "__CITE_".concat(value.index, "__");
|
|
1443
|
-
processedContent = processedContent.replaceAll(key, placeholder);
|
|
1444
|
-
value._displayIndex = displayIndex++;
|
|
1445
|
-
value._placeholder = placeholder;
|
|
1446
|
-
}
|
|
1447
|
-
|
|
1448
|
-
// Phase 2: Replace placeholders with sequential display indices.
|
|
1449
|
-
} catch (err) {
|
|
1450
|
-
_iterator2.e(err);
|
|
1451
|
-
} finally {
|
|
1452
|
-
_iterator2.f();
|
|
1453
|
-
}
|
|
1454
|
-
var _iterator3 = _createForOfIteratorHelper(citedRefs),
|
|
1455
|
-
_step3;
|
|
1456
|
-
try {
|
|
1457
|
-
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
1458
|
-
var _step3$value = _slicedToArray(_step3.value, 2),
|
|
1459
|
-
_value = _step3$value[1];
|
|
1460
|
-
processedContent = processedContent.replaceAll(_value._placeholder, "<sup><strong>".concat(_value._displayIndex, "</strong></sup>"));
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
// if we have multiple references, add a comma to ensure we don't concatenate numbers.
|
|
1464
|
-
} catch (err) {
|
|
1465
|
-
_iterator3.e(err);
|
|
1466
|
-
} finally {
|
|
1467
|
-
_iterator3.f();
|
|
1468
|
-
}
|
|
1469
|
-
processedContent = processedContent.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');
|
|
1470
|
-
processedContent += '<br><br>';
|
|
1471
|
-
var _iterator4 = _createForOfIteratorHelper(citedRefs),
|
|
1472
|
-
_step4;
|
|
1473
|
-
try {
|
|
1474
|
-
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
1475
|
-
var _step4$value = _slicedToArray(_step4.value, 2),
|
|
1476
|
-
_key = _step4$value[0],
|
|
1477
|
-
_value2 = _step4$value[1];
|
|
1478
|
-
var label = _value2.text || _key;
|
|
1479
|
-
processedContent += _value2.link ? "**".concat(_value2._displayIndex, "**. [").concat(label, "](").concat(_value2.link, ")<br>") : "**".concat(_value2._displayIndex, "**. ").concat(label, "<br>");
|
|
1480
|
-
}
|
|
1481
|
-
} catch (err) {
|
|
1482
|
-
_iterator4.e(err);
|
|
1483
|
-
} finally {
|
|
1484
|
-
_iterator4.f();
|
|
1485
|
-
}
|
|
1486
|
-
}
|
|
1487
|
-
}
|
|
1488
|
-
message.content = processedContent;
|
|
1489
|
-
message.htmlContent = parseMarkdownContent(processedContent, message);
|
|
1349
|
+
var _message$rawContent;
|
|
1350
|
+
message.rawContent = (_message$rawContent = message.rawContent) !== null && _message$rawContent !== void 0 ? _message$rawContent : message.content;
|
|
1351
|
+
updateMessagePresentation(message, message.references);
|
|
1490
1352
|
}
|
|
1491
1353
|
this.addMessageInternal(message);
|
|
1492
1354
|
this.hidePlaceholder();
|
|
1493
1355
|
this.$nextTick(function () {
|
|
1494
1356
|
// Render any pending charts once the DOM is updated
|
|
1495
1357
|
renderChartsInMessage(message);
|
|
1496
|
-
|
|
1358
|
+
_this5.scrollToBottom();
|
|
1497
1359
|
});
|
|
1498
1360
|
},
|
|
1499
1361
|
addMessages: function addMessages(messages) {
|
|
1500
|
-
var
|
|
1362
|
+
var _this6 = this;
|
|
1501
1363
|
for (var i = 0; i < messages.length; i++) {
|
|
1502
1364
|
this.addMessageInternal(messages[i]);
|
|
1503
1365
|
}
|
|
1504
1366
|
this.hidePlaceholder();
|
|
1505
1367
|
this.$nextTick(function () {
|
|
1506
|
-
|
|
1368
|
+
_this6.scrollToBottom();
|
|
1507
1369
|
});
|
|
1508
1370
|
},
|
|
1509
1371
|
hidePlaceholder: function hidePlaceholder() {
|
|
@@ -1580,7 +1442,7 @@ window.openAIChatManager = function () {
|
|
|
1580
1442
|
this.prompt = '';
|
|
1581
1443
|
},
|
|
1582
1444
|
startRecording: function startRecording() {
|
|
1583
|
-
var
|
|
1445
|
+
var _this7 = this;
|
|
1584
1446
|
if (this.isRecording || !this.connection) {
|
|
1585
1447
|
return;
|
|
1586
1448
|
}
|
|
@@ -1592,27 +1454,27 @@ window.openAIChatManager = function () {
|
|
|
1592
1454
|
}
|
|
1593
1455
|
}).then(function (stream) {
|
|
1594
1456
|
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
|
-
|
|
1457
|
+
_this7.mediaRecorder = new MediaRecorder(stream, {
|
|
1596
1458
|
mimeType: mimeType,
|
|
1597
1459
|
audioBitsPerSecond: 128000
|
|
1598
1460
|
});
|
|
1599
|
-
|
|
1600
|
-
|
|
1461
|
+
_this7.preRecordingPrompt = _this7.prompt;
|
|
1462
|
+
_this7._audioInputSent = false;
|
|
1601
1463
|
var subject = new signalR.Subject();
|
|
1602
|
-
var profileId =
|
|
1603
|
-
var sessionId =
|
|
1464
|
+
var profileId = _this7.getProfileId();
|
|
1465
|
+
var sessionId = _this7.getSessionId() || '';
|
|
1604
1466
|
var pendingChunk = Promise.resolve();
|
|
1605
|
-
|
|
1467
|
+
_this7.mediaRecorder.addEventListener('dataavailable', function (e) {
|
|
1606
1468
|
if (e.data && e.data.size > 0) {
|
|
1607
|
-
pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
1469
|
+
pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7() {
|
|
1608
1470
|
var data, uint8Array, binaryString, base64;
|
|
1609
|
-
return _regenerator().w(function (
|
|
1610
|
-
while (1) switch (
|
|
1471
|
+
return _regenerator().w(function (_context7) {
|
|
1472
|
+
while (1) switch (_context7.n) {
|
|
1611
1473
|
case 0:
|
|
1612
|
-
|
|
1474
|
+
_context7.n = 1;
|
|
1613
1475
|
return e.data.arrayBuffer();
|
|
1614
1476
|
case 1:
|
|
1615
|
-
data =
|
|
1477
|
+
data = _context7.v;
|
|
1616
1478
|
uint8Array = new Uint8Array(data);
|
|
1617
1479
|
binaryString = uint8Array.reduce(function (str, _byte) {
|
|
1618
1480
|
return str + String.fromCharCode(_byte);
|
|
@@ -1620,13 +1482,13 @@ window.openAIChatManager = function () {
|
|
|
1620
1482
|
base64 = btoa(binaryString);
|
|
1621
1483
|
subject.next(base64);
|
|
1622
1484
|
case 2:
|
|
1623
|
-
return
|
|
1485
|
+
return _context7.a(2);
|
|
1624
1486
|
}
|
|
1625
|
-
},
|
|
1487
|
+
}, _callee7);
|
|
1626
1488
|
})));
|
|
1627
1489
|
}
|
|
1628
1490
|
});
|
|
1629
|
-
|
|
1491
|
+
_this7.mediaRecorder.addEventListener('stop', function () {
|
|
1630
1492
|
stream.getTracks().forEach(function (track) {
|
|
1631
1493
|
return track.stop();
|
|
1632
1494
|
});
|
|
@@ -1635,10 +1497,10 @@ window.openAIChatManager = function () {
|
|
|
1635
1497
|
});
|
|
1636
1498
|
});
|
|
1637
1499
|
var language = navigator.language || document.documentElement.lang || 'en-US';
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1500
|
+
_this7.connection.send("SendAudioStream", profileId, sessionId, subject, mimeType, language);
|
|
1501
|
+
_this7.mediaRecorder.start(250);
|
|
1502
|
+
_this7.isRecording = true;
|
|
1503
|
+
_this7.updateMicButton();
|
|
1642
1504
|
})["catch"](function (err) {
|
|
1643
1505
|
console.error('Microphone access denied:', err);
|
|
1644
1506
|
});
|
|
@@ -1671,7 +1533,7 @@ window.openAIChatManager = function () {
|
|
|
1671
1533
|
}
|
|
1672
1534
|
},
|
|
1673
1535
|
streamMessage: function streamMessage(profileId, trimmedPrompt, sessionProfileId) {
|
|
1674
|
-
var
|
|
1536
|
+
var _this8 = this;
|
|
1675
1537
|
if (this.stream) {
|
|
1676
1538
|
this.stream.dispose();
|
|
1677
1539
|
this.stream = null;
|
|
@@ -1688,14 +1550,14 @@ window.openAIChatManager = function () {
|
|
|
1688
1550
|
var currentSessionId = this.getSessionId();
|
|
1689
1551
|
this.stream = this.connection.stream("SendMessage", profileId, trimmedPrompt, currentSessionId, sessionProfileId).subscribe({
|
|
1690
1552
|
next: function next(chunk) {
|
|
1691
|
-
var message =
|
|
1553
|
+
var message = _this8.messages[messageIndex];
|
|
1692
1554
|
if (!message) {
|
|
1693
1555
|
if (chunk.sessionId && !currentSessionId) {
|
|
1694
|
-
|
|
1556
|
+
_this8.initializeSession(chunk.sessionId);
|
|
1695
1557
|
}
|
|
1696
|
-
|
|
1558
|
+
_this8.hideTypingIndicator();
|
|
1697
1559
|
// Re-assign the index after hiding the typing indicator.
|
|
1698
|
-
messageIndex =
|
|
1560
|
+
messageIndex = _this8.messages.length;
|
|
1699
1561
|
var newMessage = {
|
|
1700
1562
|
id: chunk.messageId,
|
|
1701
1563
|
role: "assistant",
|
|
@@ -1705,16 +1567,16 @@ window.openAIChatManager = function () {
|
|
|
1705
1567
|
isStreaming: true,
|
|
1706
1568
|
userRating: null
|
|
1707
1569
|
};
|
|
1708
|
-
|
|
1570
|
+
_this8.messages.push(newMessage);
|
|
1709
1571
|
message = newMessage;
|
|
1710
1572
|
}
|
|
1711
1573
|
if (chunk.title && (!message.title || message.title !== chunk.title)) {
|
|
1712
1574
|
message.title = chunk.title;
|
|
1713
1575
|
}
|
|
1714
1576
|
if (chunk.references && _typeof(chunk.references) === "object" && Object.keys(chunk.references).length) {
|
|
1715
|
-
for (var
|
|
1577
|
+
for (var _i4 = 0, _Object$entries2 = Object.entries(chunk.references); _i4 < _Object$entries2.length; _i4++) {
|
|
1716
1578
|
var _normalizeReference2;
|
|
1717
|
-
var _Object$entries2$_i = _slicedToArray(_Object$entries2[
|
|
1579
|
+
var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i4], 2),
|
|
1718
1580
|
key = _Object$entries2$_i[0],
|
|
1719
1581
|
value = _Object$entries2$_i[1];
|
|
1720
1582
|
references[key] = (_normalizeReference2 = normalizeReference(value)) !== null && _normalizeReference2 !== void 0 ? _normalizeReference2 : {};
|
|
@@ -1729,62 +1591,52 @@ window.openAIChatManager = function () {
|
|
|
1729
1591
|
if (chunk.responseId) {
|
|
1730
1592
|
lastResponseId = chunk.responseId;
|
|
1731
1593
|
}
|
|
1732
|
-
|
|
1733
|
-
for (var _i4 = 0, _Object$entries3 = Object.entries(references); _i4 < _Object$entries3.length; _i4++) {
|
|
1734
|
-
var _Object$entries3$_i = _slicedToArray(_Object$entries3[_i4], 2),
|
|
1735
|
-
_key2 = _Object$entries3$_i[0],
|
|
1736
|
-
_value3 = _Object$entries3$_i[1];
|
|
1737
|
-
processedContent = processedContent.replaceAll(_key2, "<sup><strong>".concat(_value3.index, "</strong></sup>"));
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1740
|
-
// Append processed content to the message.
|
|
1741
|
-
// if we have multiple references, add a comma to ensure we don't concatenate numbers.
|
|
1742
|
-
content += processedContent.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');
|
|
1594
|
+
content += chunk.content;
|
|
1743
1595
|
}
|
|
1744
1596
|
|
|
1745
1597
|
// Update the existing message
|
|
1746
|
-
message.
|
|
1747
|
-
message
|
|
1748
|
-
|
|
1749
|
-
|
|
1598
|
+
message.rawContent = content;
|
|
1599
|
+
updateMessagePresentation(message, references);
|
|
1600
|
+
_this8.messages[messageIndex] = message;
|
|
1601
|
+
_this8.$nextTick(function () {
|
|
1750
1602
|
renderChartsInMessage(message);
|
|
1751
|
-
|
|
1603
|
+
_this8.scrollToBottom();
|
|
1752
1604
|
});
|
|
1753
1605
|
},
|
|
1754
1606
|
complete: function complete() {
|
|
1755
|
-
var
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
var msg =
|
|
1607
|
+
var _this8$stream;
|
|
1608
|
+
_this8.processReferences(references, messageIndex);
|
|
1609
|
+
_this8.streamingFinished();
|
|
1610
|
+
var msg = _this8.messages[messageIndex];
|
|
1759
1611
|
if (msg) {
|
|
1760
1612
|
msg.isStreaming = false;
|
|
1761
1613
|
}
|
|
1762
1614
|
if (!msg || !msg.content) {
|
|
1763
1615
|
// No content received at all.
|
|
1764
|
-
|
|
1616
|
+
_this8.hideTypingIndicator();
|
|
1765
1617
|
}
|
|
1766
1618
|
|
|
1767
1619
|
// Trigger text-to-speech only in conversation mode.
|
|
1768
|
-
if (
|
|
1769
|
-
|
|
1620
|
+
if (_this8.isConversationMode && _this8.textToSpeechEnabled && msg && msg.content) {
|
|
1621
|
+
_this8.synthesizeSpeech(msg.content);
|
|
1770
1622
|
}
|
|
1771
|
-
(
|
|
1772
|
-
|
|
1623
|
+
(_this8$stream = _this8.stream) === null || _this8$stream === void 0 || _this8$stream.dispose();
|
|
1624
|
+
_this8.stream = null;
|
|
1773
1625
|
},
|
|
1774
1626
|
error: function error(err) {
|
|
1775
|
-
var
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
var msg =
|
|
1627
|
+
var _this8$stream2;
|
|
1628
|
+
_this8.processReferences(references, messageIndex);
|
|
1629
|
+
_this8.streamingFinished();
|
|
1630
|
+
var msg = _this8.messages[messageIndex];
|
|
1779
1631
|
if (msg) {
|
|
1780
1632
|
msg.isStreaming = false;
|
|
1781
1633
|
}
|
|
1782
|
-
|
|
1783
|
-
if (!
|
|
1784
|
-
|
|
1634
|
+
_this8.hideTypingIndicator();
|
|
1635
|
+
if (!_this8.isNavigatingAway) {
|
|
1636
|
+
_this8.addMessage(_this8.getServiceDownMessage());
|
|
1785
1637
|
}
|
|
1786
|
-
(
|
|
1787
|
-
|
|
1638
|
+
(_this8$stream2 = _this8.stream) === null || _this8$stream2 === void 0 || _this8$stream2.dispose();
|
|
1639
|
+
_this8.stream = null;
|
|
1788
1640
|
console.error("Stream error:", err);
|
|
1789
1641
|
}
|
|
1790
1642
|
});
|
|
@@ -1798,92 +1650,17 @@ window.openAIChatManager = function () {
|
|
|
1798
1650
|
return newMessage;
|
|
1799
1651
|
},
|
|
1800
1652
|
processReferences: function processReferences(references, messageIndex) {
|
|
1801
|
-
var
|
|
1653
|
+
var _this9 = this;
|
|
1802
1654
|
references = normalizeReferences(references);
|
|
1803
1655
|
if (Object.keys(references).length) {
|
|
1656
|
+
var _ref15, _message$rawContent2;
|
|
1804
1657
|
var message = this.messages[messageIndex];
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
// Only include references that were actually cited in the response.
|
|
1808
|
-
// Check both raw [doc:N] markers and already-rendered <sup> tags from streaming.
|
|
1809
|
-
var citedRefs = Object.entries(references).filter(function (_ref1) {
|
|
1810
|
-
var _ref10 = _slicedToArray(_ref1, 2),
|
|
1811
|
-
key = _ref10[0],
|
|
1812
|
-
value = _ref10[1];
|
|
1813
|
-
return content.includes(key) || content.includes("<sup><strong>".concat(value.index, "</strong></sup>"));
|
|
1814
|
-
});
|
|
1815
|
-
if (!citedRefs.length) {
|
|
1816
|
-
return;
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
// Sort by original index so display indices follow a natural order.
|
|
1820
|
-
citedRefs.sort(function (_ref11, _ref12) {
|
|
1821
|
-
var _ref13 = _slicedToArray(_ref11, 2),
|
|
1822
|
-
a = _ref13[1];
|
|
1823
|
-
var _ref14 = _slicedToArray(_ref12, 2),
|
|
1824
|
-
b = _ref14[1];
|
|
1825
|
-
return a.index - b.index;
|
|
1826
|
-
});
|
|
1827
|
-
|
|
1828
|
-
// Phase 1: Replace all markers with unique placeholders to avoid collisions during remapping.
|
|
1829
|
-
var processed = content.trim();
|
|
1830
|
-
var displayIndex = 1;
|
|
1831
|
-
var _iterator5 = _createForOfIteratorHelper(citedRefs),
|
|
1832
|
-
_step5;
|
|
1833
|
-
try {
|
|
1834
|
-
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
1835
|
-
var _step5$value = _slicedToArray(_step5.value, 2),
|
|
1836
|
-
key = _step5$value[0],
|
|
1837
|
-
value = _step5$value[1];
|
|
1838
|
-
var placeholder = "__CITE_".concat(value.index, "__");
|
|
1839
|
-
processed = processed.replaceAll(key, placeholder);
|
|
1840
|
-
processed = processed.replaceAll("<sup><strong>".concat(value.index, "</strong></sup>"), placeholder);
|
|
1841
|
-
value._displayIndex = displayIndex++;
|
|
1842
|
-
value._placeholder = placeholder;
|
|
1843
|
-
}
|
|
1844
|
-
|
|
1845
|
-
// Phase 2: Replace placeholders with sequential display indices.
|
|
1846
|
-
} catch (err) {
|
|
1847
|
-
_iterator5.e(err);
|
|
1848
|
-
} finally {
|
|
1849
|
-
_iterator5.f();
|
|
1850
|
-
}
|
|
1851
|
-
var _iterator6 = _createForOfIteratorHelper(citedRefs),
|
|
1852
|
-
_step6;
|
|
1853
|
-
try {
|
|
1854
|
-
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
1855
|
-
var _step6$value = _slicedToArray(_step6.value, 2),
|
|
1856
|
-
_value4 = _step6$value[1];
|
|
1857
|
-
processed = processed.replaceAll(_value4._placeholder, "<sup><strong>".concat(_value4._displayIndex, "</strong></sup>"));
|
|
1858
|
-
}
|
|
1859
|
-
} catch (err) {
|
|
1860
|
-
_iterator6.e(err);
|
|
1861
|
-
} finally {
|
|
1862
|
-
_iterator6.f();
|
|
1863
|
-
}
|
|
1864
|
-
processed = processed.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');
|
|
1865
|
-
processed += '<br><br>';
|
|
1866
|
-
var _iterator7 = _createForOfIteratorHelper(citedRefs),
|
|
1867
|
-
_step7;
|
|
1868
|
-
try {
|
|
1869
|
-
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
1870
|
-
var _step7$value = _slicedToArray(_step7.value, 2),
|
|
1871
|
-
_key3 = _step7$value[0],
|
|
1872
|
-
_value5 = _step7$value[1];
|
|
1873
|
-
var label = _value5.text || _key3;
|
|
1874
|
-
processed += _value5.link ? "**".concat(_value5._displayIndex, "**. [").concat(label, "](").concat(_value5.link, ")<br>") : "**".concat(_value5._displayIndex, "**. ").concat(label, "<br>");
|
|
1875
|
-
}
|
|
1876
|
-
} catch (err) {
|
|
1877
|
-
_iterator7.e(err);
|
|
1878
|
-
} finally {
|
|
1879
|
-
_iterator7.f();
|
|
1880
|
-
}
|
|
1881
|
-
message.content = processed;
|
|
1882
|
-
message.htmlContent = parseMarkdownContent(processed, message);
|
|
1658
|
+
message.rawContent = (_ref15 = (_message$rawContent2 = message.rawContent) !== null && _message$rawContent2 !== void 0 ? _message$rawContent2 : message.content) !== null && _ref15 !== void 0 ? _ref15 : '';
|
|
1659
|
+
updateMessagePresentation(message, references);
|
|
1883
1660
|
this.messages[messageIndex] = message;
|
|
1884
1661
|
this.$nextTick(function () {
|
|
1885
1662
|
renderChartsInMessage(message);
|
|
1886
|
-
|
|
1663
|
+
_this9.scrollToBottom();
|
|
1887
1664
|
});
|
|
1888
1665
|
}
|
|
1889
1666
|
},
|
|
@@ -1933,6 +1710,23 @@ window.openAIChatManager = function () {
|
|
|
1933
1710
|
}
|
|
1934
1711
|
this.stopAudio(false);
|
|
1935
1712
|
},
|
|
1713
|
+
updateTtsPlaybackButtons: function updateTtsPlaybackButtons() {
|
|
1714
|
+
var _this0 = this;
|
|
1715
|
+
if (!this.chatContainer) {
|
|
1716
|
+
return;
|
|
1717
|
+
}
|
|
1718
|
+
var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');
|
|
1719
|
+
buttons.forEach(function (button) {
|
|
1720
|
+
var buttonIndex = Number(button.getAttribute('data-tts-message-index'));
|
|
1721
|
+
var isPlaying = buttonIndex === _this0.ttsPlayingMessageIndex;
|
|
1722
|
+
var iconHtml = isPlaying ? '<i class="fa-solid fa-circle-pause"></i>' : '<i class="fa-solid fa-circle-play"></i>';
|
|
1723
|
+
button.classList.toggle('tts-playing', isPlaying);
|
|
1724
|
+
button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');
|
|
1725
|
+
button.replaceChildren(DOMPurify.sanitize(iconHtml, {
|
|
1726
|
+
RETURN_DOM_FRAGMENT: true
|
|
1727
|
+
}));
|
|
1728
|
+
});
|
|
1729
|
+
},
|
|
1936
1730
|
synthesizeSpeech: function synthesizeSpeech(text, cacheIndex) {
|
|
1937
1731
|
var _this1 = this;
|
|
1938
1732
|
if (!this.textToSpeechEnabled || !text || !this.connection) {
|
|
@@ -1946,9 +1740,13 @@ window.openAIChatManager = function () {
|
|
|
1946
1740
|
_this1.isPlayingAudio = false;
|
|
1947
1741
|
_this1.ttsPlayingMessageIndex = -1;
|
|
1948
1742
|
_this1._ttsCacheIndex = -1;
|
|
1743
|
+
_this1.$nextTick(function () {
|
|
1744
|
+
return _this1.updateTtsPlaybackButtons();
|
|
1745
|
+
});
|
|
1949
1746
|
});
|
|
1950
1747
|
},
|
|
1951
1748
|
toggleMessageTts: function toggleMessageTts(message, index) {
|
|
1749
|
+
var _this10 = this;
|
|
1952
1750
|
if (this.ttsPlayingMessageIndex === index) {
|
|
1953
1751
|
this.stopAudio();
|
|
1954
1752
|
return;
|
|
@@ -1960,6 +1758,9 @@ window.openAIChatManager = function () {
|
|
|
1960
1758
|
}
|
|
1961
1759
|
}));
|
|
1962
1760
|
this.ttsPlayingMessageIndex = index;
|
|
1761
|
+
this.$nextTick(function () {
|
|
1762
|
+
return _this10.updateTtsPlaybackButtons();
|
|
1763
|
+
});
|
|
1963
1764
|
if (this.ttsAudioCache[index]) {
|
|
1964
1765
|
this.playAudioBlob(this.ttsAudioCache[index]);
|
|
1965
1766
|
return;
|
|
@@ -1967,10 +1768,14 @@ window.openAIChatManager = function () {
|
|
|
1967
1768
|
this.synthesizeSpeech(message.content, index);
|
|
1968
1769
|
},
|
|
1969
1770
|
playCollectedAudio: function playCollectedAudio() {
|
|
1771
|
+
var _this11 = this;
|
|
1970
1772
|
if (this.audioChunks.length === 0) {
|
|
1971
1773
|
if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {
|
|
1972
1774
|
this.isPlayingAudio = false;
|
|
1973
1775
|
this.ttsPlayingMessageIndex = -1;
|
|
1776
|
+
this.$nextTick(function () {
|
|
1777
|
+
return _this11.updateTtsPlaybackButtons();
|
|
1778
|
+
});
|
|
1974
1779
|
}
|
|
1975
1780
|
return;
|
|
1976
1781
|
}
|
|
@@ -1979,18 +1784,18 @@ window.openAIChatManager = function () {
|
|
|
1979
1784
|
}, 0);
|
|
1980
1785
|
var combined = new Uint8Array(totalLength);
|
|
1981
1786
|
var offset = 0;
|
|
1982
|
-
var
|
|
1983
|
-
|
|
1787
|
+
var _iterator5 = _createForOfIteratorHelper(this.audioChunks),
|
|
1788
|
+
_step5;
|
|
1984
1789
|
try {
|
|
1985
|
-
for (
|
|
1986
|
-
var chunk =
|
|
1790
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
1791
|
+
var chunk = _step5.value;
|
|
1987
1792
|
combined.set(chunk, offset);
|
|
1988
1793
|
offset += chunk.length;
|
|
1989
1794
|
}
|
|
1990
1795
|
} catch (err) {
|
|
1991
|
-
|
|
1796
|
+
_iterator5.e(err);
|
|
1992
1797
|
} finally {
|
|
1993
|
-
|
|
1798
|
+
_iterator5.f();
|
|
1994
1799
|
}
|
|
1995
1800
|
this.audioChunks = [];
|
|
1996
1801
|
var blob = new Blob([combined], {
|
|
@@ -2009,45 +1814,53 @@ window.openAIChatManager = function () {
|
|
|
2009
1814
|
this.playAudioBlob(blob);
|
|
2010
1815
|
},
|
|
2011
1816
|
playAudioBlob: function playAudioBlob(blob) {
|
|
2012
|
-
var
|
|
1817
|
+
var _this12 = this;
|
|
2013
1818
|
var url = URL.createObjectURL(blob);
|
|
2014
1819
|
var audio = new Audio(url);
|
|
2015
1820
|
this.currentAudioUrl = url;
|
|
2016
1821
|
this.currentAudioElement = audio;
|
|
2017
1822
|
this.isPlayingAudio = true;
|
|
2018
1823
|
audio.addEventListener('ended', function () {
|
|
2019
|
-
|
|
2020
|
-
|
|
1824
|
+
_this12.currentAudioElement = null;
|
|
1825
|
+
_this12.currentAudioUrl = null;
|
|
2021
1826
|
URL.revokeObjectURL(url);
|
|
2022
|
-
|
|
1827
|
+
_this12.playNextInQueue();
|
|
2023
1828
|
});
|
|
2024
1829
|
audio.addEventListener('error', function () {
|
|
2025
|
-
|
|
2026
|
-
|
|
1830
|
+
_this12.currentAudioElement = null;
|
|
1831
|
+
_this12.currentAudioUrl = null;
|
|
2027
1832
|
URL.revokeObjectURL(url);
|
|
2028
|
-
|
|
1833
|
+
_this12.playNextInQueue();
|
|
2029
1834
|
});
|
|
2030
1835
|
audio.play()["catch"](function (err) {
|
|
2031
1836
|
console.error("Audio playback error:", err);
|
|
2032
|
-
|
|
2033
|
-
|
|
1837
|
+
_this12.currentAudioElement = null;
|
|
1838
|
+
_this12.currentAudioUrl = null;
|
|
2034
1839
|
URL.revokeObjectURL(url);
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
1840
|
+
_this12.audioPlayQueue = [];
|
|
1841
|
+
_this12.isPlayingAudio = false;
|
|
1842
|
+
_this12.ttsPlayingMessageIndex = -1;
|
|
1843
|
+
_this12.$nextTick(function () {
|
|
1844
|
+
return _this12.updateTtsPlaybackButtons();
|
|
1845
|
+
});
|
|
2038
1846
|
});
|
|
2039
1847
|
},
|
|
2040
1848
|
playNextInQueue: function playNextInQueue() {
|
|
1849
|
+
var _this13 = this;
|
|
2041
1850
|
if (this.audioPlayQueue.length > 0) {
|
|
2042
1851
|
var nextBlob = this.audioPlayQueue.shift();
|
|
2043
1852
|
this.playAudioBlob(nextBlob);
|
|
2044
1853
|
} else {
|
|
2045
1854
|
this.isPlayingAudio = false;
|
|
2046
1855
|
this.ttsPlayingMessageIndex = -1;
|
|
1856
|
+
this.$nextTick(function () {
|
|
1857
|
+
return _this13.updateTtsPlaybackButtons();
|
|
1858
|
+
});
|
|
2047
1859
|
this.conversationModeOnAudioEnded();
|
|
2048
1860
|
}
|
|
2049
1861
|
},
|
|
2050
1862
|
stopAudio: function stopAudio() {
|
|
1863
|
+
var _this14 = this;
|
|
2051
1864
|
if (this.currentAudioElement) {
|
|
2052
1865
|
this.currentAudioElement.pause();
|
|
2053
1866
|
this.currentAudioElement.currentTime = 0;
|
|
@@ -2061,6 +1874,9 @@ window.openAIChatManager = function () {
|
|
|
2061
1874
|
this.audioPlayQueue = [];
|
|
2062
1875
|
this.isPlayingAudio = false;
|
|
2063
1876
|
this.ttsPlayingMessageIndex = -1;
|
|
1877
|
+
this.$nextTick(function () {
|
|
1878
|
+
return _this14.updateTtsPlaybackButtons();
|
|
1879
|
+
});
|
|
2064
1880
|
},
|
|
2065
1881
|
toggleConversationMode: function toggleConversationMode() {
|
|
2066
1882
|
if (this.isConversationMode) {
|
|
@@ -2070,7 +1886,7 @@ window.openAIChatManager = function () {
|
|
|
2070
1886
|
}
|
|
2071
1887
|
},
|
|
2072
1888
|
startConversationMode: function startConversationMode() {
|
|
2073
|
-
var
|
|
1889
|
+
var _this15 = this;
|
|
2074
1890
|
if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {
|
|
2075
1891
|
return;
|
|
2076
1892
|
}
|
|
@@ -2090,12 +1906,12 @@ window.openAIChatManager = function () {
|
|
|
2090
1906
|
}
|
|
2091
1907
|
}).then(function (stream) {
|
|
2092
1908
|
var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus') ? 'audio/ogg;codecs=opus' : MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
|
|
2093
|
-
|
|
1909
|
+
_this15.mediaRecorder = new MediaRecorder(stream, {
|
|
2094
1910
|
mimeType: mimeType,
|
|
2095
1911
|
audioBitsPerSecond: 128000
|
|
2096
1912
|
});
|
|
2097
|
-
|
|
2098
|
-
|
|
1913
|
+
_this15._conversationSubject = new signalR.Subject();
|
|
1914
|
+
_this15._conversationStream = stream;
|
|
2099
1915
|
|
|
2100
1916
|
// Create an AnalyserNode for volume-based interrupt detection.
|
|
2101
1917
|
// During TTS playback, detect when the user speaks above
|
|
@@ -2104,20 +1920,20 @@ window.openAIChatManager = function () {
|
|
|
2104
1920
|
// speaker echo so the STT stream has no gaps.
|
|
2105
1921
|
var AudioCtx = window.AudioContext || window.webkitAudioContext;
|
|
2106
1922
|
if (AudioCtx) {
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
var micSource =
|
|
2111
|
-
micSource.connect(
|
|
1923
|
+
_this15._conversationAudioCtx = new AudioCtx();
|
|
1924
|
+
_this15._conversationAnalyser = _this15._conversationAudioCtx.createAnalyser();
|
|
1925
|
+
_this15._conversationAnalyser.fftSize = 256;
|
|
1926
|
+
var micSource = _this15._conversationAudioCtx.createMediaStreamSource(stream);
|
|
1927
|
+
micSource.connect(_this15._conversationAnalyser);
|
|
2112
1928
|
}
|
|
2113
1929
|
var pendingChunk = Promise.resolve();
|
|
2114
|
-
var analyser =
|
|
1930
|
+
var analyser = _this15._conversationAnalyser;
|
|
2115
1931
|
var interruptVolumeThreshold = 30;
|
|
2116
|
-
|
|
1932
|
+
_this15.mediaRecorder.addEventListener('dataavailable', function (e) {
|
|
2117
1933
|
if (e.data && e.data.size > 0) {
|
|
2118
1934
|
// During TTS playback, check mic volume to detect
|
|
2119
1935
|
// user interruption (speaking above threshold).
|
|
2120
|
-
if (
|
|
1936
|
+
if (_this15.isPlayingAudio && analyser) {
|
|
2121
1937
|
var freqData = new Uint8Array(analyser.frequencyBinCount);
|
|
2122
1938
|
analyser.getByteFrequencyData(freqData);
|
|
2123
1939
|
var sum = 0;
|
|
@@ -2127,61 +1943,61 @@ window.openAIChatManager = function () {
|
|
|
2127
1943
|
var avg = sum / freqData.length;
|
|
2128
1944
|
if (avg >= interruptVolumeThreshold) {
|
|
2129
1945
|
// User is speaking — interrupt TTS playback.
|
|
2130
|
-
|
|
1946
|
+
_this15.stopAudio();
|
|
2131
1947
|
}
|
|
2132
1948
|
}
|
|
2133
1949
|
|
|
2134
1950
|
// Always send audio to STT — browser echo cancellation
|
|
2135
1951
|
// handles speaker echo; continuous audio avoids gaps
|
|
2136
1952
|
// that increase recognition latency.
|
|
2137
|
-
pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
1953
|
+
pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
|
|
2138
1954
|
var data, uint8Array, binaryString, base64;
|
|
2139
|
-
return _regenerator().w(function (
|
|
2140
|
-
while (1) switch (
|
|
1955
|
+
return _regenerator().w(function (_context8) {
|
|
1956
|
+
while (1) switch (_context8.n) {
|
|
2141
1957
|
case 0:
|
|
2142
|
-
|
|
1958
|
+
_context8.n = 1;
|
|
2143
1959
|
return e.data.arrayBuffer();
|
|
2144
1960
|
case 1:
|
|
2145
|
-
data =
|
|
1961
|
+
data = _context8.v;
|
|
2146
1962
|
uint8Array = new Uint8Array(data);
|
|
2147
1963
|
binaryString = uint8Array.reduce(function (str, _byte2) {
|
|
2148
1964
|
return str + String.fromCharCode(_byte2);
|
|
2149
1965
|
}, '');
|
|
2150
1966
|
base64 = btoa(binaryString);
|
|
2151
1967
|
try {
|
|
2152
|
-
|
|
1968
|
+
_this15._conversationSubject.next(base64);
|
|
2153
1969
|
} catch (err) {
|
|
2154
1970
|
// Subject may have been completed already.
|
|
2155
1971
|
}
|
|
2156
1972
|
case 2:
|
|
2157
|
-
return
|
|
1973
|
+
return _context8.a(2);
|
|
2158
1974
|
}
|
|
2159
|
-
},
|
|
1975
|
+
}, _callee8);
|
|
2160
1976
|
})));
|
|
2161
1977
|
}
|
|
2162
1978
|
});
|
|
2163
|
-
|
|
1979
|
+
_this15.mediaRecorder.addEventListener('stop', function () {
|
|
2164
1980
|
stream.getTracks().forEach(function (track) {
|
|
2165
1981
|
return track.stop();
|
|
2166
1982
|
});
|
|
2167
1983
|
pendingChunk.then(function () {
|
|
2168
1984
|
try {
|
|
2169
|
-
|
|
1985
|
+
_this15._conversationSubject.complete();
|
|
2170
1986
|
} catch (err) {
|
|
2171
1987
|
// Already completed.
|
|
2172
1988
|
}
|
|
2173
1989
|
});
|
|
2174
1990
|
});
|
|
2175
|
-
var profileId =
|
|
2176
|
-
var sessionId =
|
|
1991
|
+
var profileId = _this15.getProfileId();
|
|
1992
|
+
var sessionId = _this15.getSessionId() || '';
|
|
2177
1993
|
var language = navigator.language || document.documentElement.lang || 'en-US';
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
1994
|
+
_this15.connection.send("StartConversation", profileId, sessionId, _this15._conversationSubject, mimeType, language);
|
|
1995
|
+
_this15.mediaRecorder.start(250);
|
|
1996
|
+
_this15.isRecording = true;
|
|
2181
1997
|
})["catch"](function (err) {
|
|
2182
1998
|
console.error('Microphone access denied:', err);
|
|
2183
|
-
|
|
2184
|
-
|
|
1999
|
+
_this15.isConversationMode = false;
|
|
2000
|
+
_this15.updateConversationButton();
|
|
2185
2001
|
});
|
|
2186
2002
|
},
|
|
2187
2003
|
stopConversationMode: function stopConversationMode() {
|
|
@@ -2308,7 +2124,7 @@ window.openAIChatManager = function () {
|
|
|
2308
2124
|
return removedCount;
|
|
2309
2125
|
},
|
|
2310
2126
|
receiveNotification: function receiveNotification(notification) {
|
|
2311
|
-
var
|
|
2127
|
+
var _this16 = this;
|
|
2312
2128
|
if (!notification || !notification.type) {
|
|
2313
2129
|
return;
|
|
2314
2130
|
}
|
|
@@ -2323,7 +2139,7 @@ window.openAIChatManager = function () {
|
|
|
2323
2139
|
}
|
|
2324
2140
|
this.scheduleNotificationDismiss(notification);
|
|
2325
2141
|
this.$nextTick(function () {
|
|
2326
|
-
|
|
2142
|
+
_this16.scrollToBottom();
|
|
2327
2143
|
});
|
|
2328
2144
|
},
|
|
2329
2145
|
updateNotification: function updateNotification(notification) {
|
|
@@ -2340,12 +2156,12 @@ window.openAIChatManager = function () {
|
|
|
2340
2156
|
}
|
|
2341
2157
|
},
|
|
2342
2158
|
scheduleNotificationDismiss: function scheduleNotificationDismiss(notification) {
|
|
2343
|
-
var
|
|
2159
|
+
var _this17 = this;
|
|
2344
2160
|
if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {
|
|
2345
2161
|
return;
|
|
2346
2162
|
}
|
|
2347
2163
|
this.notificationDismissTimers[notification.type] = setTimeout(function () {
|
|
2348
|
-
|
|
2164
|
+
_this17.removeNotification(notification.type);
|
|
2349
2165
|
}, notification.autoDismissMs);
|
|
2350
2166
|
},
|
|
2351
2167
|
clearNotificationDismiss: function clearNotificationDismiss(notificationType) {
|
|
@@ -2375,31 +2191,32 @@ window.openAIChatManager = function () {
|
|
|
2375
2191
|
});
|
|
2376
2192
|
},
|
|
2377
2193
|
scrollToBottom: function scrollToBottom() {
|
|
2378
|
-
var
|
|
2194
|
+
var _this18 = this;
|
|
2379
2195
|
if (!this.autoScroll) {
|
|
2380
2196
|
return;
|
|
2381
2197
|
}
|
|
2382
2198
|
setTimeout(function () {
|
|
2383
|
-
|
|
2199
|
+
_this18.chatContainer.scrollTop = _this18.chatContainer.scrollHeight - _this18.chatContainer.clientHeight;
|
|
2384
2200
|
}, 50);
|
|
2385
2201
|
},
|
|
2386
2202
|
handleUserInput: function handleUserInput(event) {
|
|
2387
2203
|
this.prompt = event.target.value;
|
|
2388
2204
|
},
|
|
2389
2205
|
getProfileId: function getProfileId() {
|
|
2390
|
-
return this.inputElement.getAttribute('data-profile-id');
|
|
2206
|
+
return this.inputElement ? this.inputElement.getAttribute('data-profile-id') : null;
|
|
2391
2207
|
},
|
|
2392
2208
|
setSessionId: function setSessionId(sessionId) {
|
|
2209
|
+
if (!this.inputElement) {
|
|
2210
|
+
return;
|
|
2211
|
+
}
|
|
2393
2212
|
this.inputElement.setAttribute('data-session-id', sessionId || '');
|
|
2394
2213
|
},
|
|
2395
2214
|
resetSession: function resetSession() {
|
|
2396
2215
|
this.stopRecording();
|
|
2216
|
+
this.rejectPendingSessionRequest('Session was reset.');
|
|
2397
2217
|
this.setSessionId('');
|
|
2398
2218
|
this.isSessionStarted = false;
|
|
2399
2219
|
this.sessionRating = null;
|
|
2400
|
-
if (this.widgetIsInitialized) {
|
|
2401
|
-
localStorage.removeItem(this.chatWidgetStateSession);
|
|
2402
|
-
}
|
|
2403
2220
|
this.messages = [];
|
|
2404
2221
|
this.documents = [];
|
|
2405
2222
|
if (!config.autoCreateSession) {
|
|
@@ -2408,6 +2225,9 @@ window.openAIChatManager = function () {
|
|
|
2408
2225
|
if (config.autoCreateSession) {
|
|
2409
2226
|
this.startNewSession();
|
|
2410
2227
|
}
|
|
2228
|
+
if (widgetBehavior && typeof widgetBehavior.onSessionReset === 'function') {
|
|
2229
|
+
widgetBehavior.onSessionReset(this, config);
|
|
2230
|
+
}
|
|
2411
2231
|
},
|
|
2412
2232
|
startNewSession: function startNewSession() {
|
|
2413
2233
|
if (!this.applyOrchestratorAvailability()) {
|
|
@@ -2417,16 +2237,94 @@ window.openAIChatManager = function () {
|
|
|
2417
2237
|
if (!profileId || !this.connection) {
|
|
2418
2238
|
return;
|
|
2419
2239
|
}
|
|
2420
|
-
this.
|
|
2240
|
+
this.requestNewSession(profileId)["catch"](function (err) {
|
|
2421
2241
|
return console.error(err);
|
|
2422
2242
|
});
|
|
2423
2243
|
},
|
|
2244
|
+
ensureSessionForDocuments: function ensureSessionForDocuments(profileId) {
|
|
2245
|
+
var _this19 = this;
|
|
2246
|
+
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9() {
|
|
2247
|
+
var sessionId;
|
|
2248
|
+
return _regenerator().w(function (_context9) {
|
|
2249
|
+
while (1) switch (_context9.n) {
|
|
2250
|
+
case 0:
|
|
2251
|
+
sessionId = _this19.getSessionId();
|
|
2252
|
+
if (!sessionId) {
|
|
2253
|
+
_context9.n = 1;
|
|
2254
|
+
break;
|
|
2255
|
+
}
|
|
2256
|
+
return _context9.a(2, sessionId);
|
|
2257
|
+
case 1:
|
|
2258
|
+
if (!(!profileId || !_this19.connection)) {
|
|
2259
|
+
_context9.n = 2;
|
|
2260
|
+
break;
|
|
2261
|
+
}
|
|
2262
|
+
return _context9.a(2, null);
|
|
2263
|
+
case 2:
|
|
2264
|
+
_context9.n = 3;
|
|
2265
|
+
return _this19.requestNewSession(profileId);
|
|
2266
|
+
case 3:
|
|
2267
|
+
return _context9.a(2, _context9.v);
|
|
2268
|
+
}
|
|
2269
|
+
}, _callee9);
|
|
2270
|
+
}))();
|
|
2271
|
+
},
|
|
2272
|
+
requestNewSession: function requestNewSession(profileId) {
|
|
2273
|
+
var _this20 = this;
|
|
2274
|
+
if (this.pendingSessionPromise) {
|
|
2275
|
+
return this.pendingSessionPromise;
|
|
2276
|
+
}
|
|
2277
|
+
if (!profileId || !this.connection) {
|
|
2278
|
+
return Promise.resolve(null);
|
|
2279
|
+
}
|
|
2280
|
+
this.pendingSessionPromise = new Promise(function (resolve, reject) {
|
|
2281
|
+
_this20.pendingSessionResolver = resolve;
|
|
2282
|
+
_this20.pendingSessionRejector = reject;
|
|
2283
|
+
_this20.pendingSessionTimeoutId = window.setTimeout(function () {
|
|
2284
|
+
_this20.rejectPendingSessionRequest('Timed out while creating a chat session.');
|
|
2285
|
+
}, 15000);
|
|
2286
|
+
});
|
|
2287
|
+
this.connection.invoke("StartSession", profileId, null)["catch"](function (err) {
|
|
2288
|
+
_this20.rejectPendingSessionRequest(err);
|
|
2289
|
+
});
|
|
2290
|
+
return this.pendingSessionPromise;
|
|
2291
|
+
},
|
|
2292
|
+
resolvePendingSessionRequest: function resolvePendingSessionRequest(sessionId) {
|
|
2293
|
+
if (this.pendingSessionResolver) {
|
|
2294
|
+
this.pendingSessionResolver(sessionId);
|
|
2295
|
+
}
|
|
2296
|
+
this.clearPendingSessionRequest();
|
|
2297
|
+
},
|
|
2298
|
+
rejectPendingSessionRequest: function rejectPendingSessionRequest(error) {
|
|
2299
|
+
if (this.pendingSessionRejector) {
|
|
2300
|
+
this.pendingSessionRejector(error);
|
|
2301
|
+
}
|
|
2302
|
+
this.clearPendingSessionRequest();
|
|
2303
|
+
},
|
|
2304
|
+
clearPendingSessionRequest: function clearPendingSessionRequest() {
|
|
2305
|
+
if (this.pendingSessionTimeoutId) {
|
|
2306
|
+
window.clearTimeout(this.pendingSessionTimeoutId);
|
|
2307
|
+
}
|
|
2308
|
+
this.pendingSessionPromise = null;
|
|
2309
|
+
this.pendingSessionResolver = null;
|
|
2310
|
+
this.pendingSessionRejector = null;
|
|
2311
|
+
this.pendingSessionTimeoutId = null;
|
|
2312
|
+
},
|
|
2424
2313
|
initializeApp: function initializeApp() {
|
|
2425
|
-
var
|
|
2314
|
+
var _this21 = this;
|
|
2426
2315
|
this.inputElement = document.querySelector(config.inputElementSelector);
|
|
2427
2316
|
this.buttonElement = document.querySelector(config.sendButtonElementSelector);
|
|
2428
2317
|
this.chatContainer = document.querySelector(config.chatContainerElementSelector);
|
|
2429
2318
|
this.placeholder = document.querySelector(config.placeholderElementSelector);
|
|
2319
|
+
if (!this.inputElement || !this.buttonElement || !this.chatContainer || !this.placeholder) {
|
|
2320
|
+
console.error('AI chat app could not initialize because one or more required elements were not found.', {
|
|
2321
|
+
inputElementSelector: config.inputElementSelector,
|
|
2322
|
+
sendButtonElementSelector: config.sendButtonElementSelector,
|
|
2323
|
+
chatContainerElementSelector: config.chatContainerElementSelector,
|
|
2324
|
+
placeholderElementSelector: config.placeholderElementSelector
|
|
2325
|
+
});
|
|
2326
|
+
return false;
|
|
2327
|
+
}
|
|
2430
2328
|
this.applyOrchestratorAvailability();
|
|
2431
2329
|
var sessionId = this.getSessionId();
|
|
2432
2330
|
if (!hasWidgetConfig && sessionId) {
|
|
@@ -2451,7 +2349,7 @@ window.openAIChatManager = function () {
|
|
|
2451
2349
|
fileInput.accept = config.allowedExtensions;
|
|
2452
2350
|
}
|
|
2453
2351
|
fileInput.addEventListener('change', function (e) {
|
|
2454
|
-
return
|
|
2352
|
+
return _this21.handleFileInputChange(e);
|
|
2455
2353
|
});
|
|
2456
2354
|
this.documentBar.parentElement.appendChild(fileInput);
|
|
2457
2355
|
|
|
@@ -2459,13 +2357,13 @@ window.openAIChatManager = function () {
|
|
|
2459
2357
|
var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;
|
|
2460
2358
|
if (inputArea) {
|
|
2461
2359
|
inputArea.addEventListener('dragover', function (e) {
|
|
2462
|
-
return
|
|
2360
|
+
return _this21.handleDragOver(e);
|
|
2463
2361
|
});
|
|
2464
2362
|
inputArea.addEventListener('dragleave', function (e) {
|
|
2465
|
-
return
|
|
2363
|
+
return _this21.handleDragLeave(e);
|
|
2466
2364
|
});
|
|
2467
2365
|
inputArea.addEventListener('drop', function (e) {
|
|
2468
|
-
return
|
|
2366
|
+
return _this21.handleDrop(e);
|
|
2469
2367
|
});
|
|
2470
2368
|
}
|
|
2471
2369
|
}
|
|
@@ -2473,55 +2371,55 @@ window.openAIChatManager = function () {
|
|
|
2473
2371
|
|
|
2474
2372
|
// Pause auto-scroll when the user manually scrolls up during streaming.
|
|
2475
2373
|
this.chatContainer.addEventListener('scroll', function () {
|
|
2476
|
-
if (!
|
|
2374
|
+
if (!_this21.stream) {
|
|
2477
2375
|
return;
|
|
2478
2376
|
}
|
|
2479
2377
|
var threshold = 30;
|
|
2480
|
-
var atBottom =
|
|
2481
|
-
|
|
2378
|
+
var atBottom = _this21.chatContainer.scrollHeight - _this21.chatContainer.clientHeight - _this21.chatContainer.scrollTop <= threshold;
|
|
2379
|
+
_this21.autoScroll = atBottom;
|
|
2482
2380
|
});
|
|
2483
2381
|
this.inputElement.addEventListener('keydown', function (event) {
|
|
2484
|
-
if (
|
|
2382
|
+
if (_this21.stream != null) {
|
|
2485
2383
|
return;
|
|
2486
2384
|
}
|
|
2487
2385
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
2488
2386
|
event.preventDefault();
|
|
2489
|
-
|
|
2387
|
+
_this21.buttonElement.click();
|
|
2490
2388
|
}
|
|
2491
2389
|
});
|
|
2492
2390
|
this.inputElement.addEventListener('input', function (e) {
|
|
2493
|
-
|
|
2391
|
+
_this21.handleUserInput(e);
|
|
2494
2392
|
if (e.target.value.trim()) {
|
|
2495
|
-
|
|
2393
|
+
_this21.buttonElement.removeAttribute('disabled');
|
|
2496
2394
|
} else {
|
|
2497
|
-
|
|
2395
|
+
_this21.buttonElement.setAttribute('disabled', true);
|
|
2498
2396
|
}
|
|
2499
2397
|
});
|
|
2500
2398
|
this.buttonElement.addEventListener('click', function () {
|
|
2501
|
-
if (
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2399
|
+
if (_this21.stream != null) {
|
|
2400
|
+
_this21.stream.dispose();
|
|
2401
|
+
_this21.stream = null;
|
|
2402
|
+
_this21.streamingFinished();
|
|
2403
|
+
_this21.hideTypingIndicator();
|
|
2506
2404
|
|
|
2507
2405
|
// Clean up: remove empty assistant message or stop streaming animation.
|
|
2508
|
-
if (
|
|
2509
|
-
var lastMsg =
|
|
2406
|
+
if (_this21.messages.length > 0) {
|
|
2407
|
+
var lastMsg = _this21.messages[_this21.messages.length - 1];
|
|
2510
2408
|
if (lastMsg.role === 'assistant' && !lastMsg.content) {
|
|
2511
|
-
|
|
2409
|
+
_this21.messages.pop();
|
|
2512
2410
|
} else if (lastMsg.isStreaming) {
|
|
2513
2411
|
lastMsg.isStreaming = false;
|
|
2514
2412
|
}
|
|
2515
2413
|
}
|
|
2516
2414
|
return;
|
|
2517
2415
|
}
|
|
2518
|
-
|
|
2416
|
+
_this21.sendMessage();
|
|
2519
2417
|
});
|
|
2520
2418
|
var promptGenerators = document.getElementsByClassName('profile-generated-prompt');
|
|
2521
2419
|
for (var i = 0; i < promptGenerators.length; i++) {
|
|
2522
2420
|
promptGenerators[i].addEventListener('click', function (e) {
|
|
2523
2421
|
e.preventDefault();
|
|
2524
|
-
|
|
2422
|
+
_this21.generatePrompt(e.target);
|
|
2525
2423
|
});
|
|
2526
2424
|
}
|
|
2527
2425
|
var chatSessions = document.getElementsByClassName('chat-session-history-item');
|
|
@@ -2533,8 +2431,8 @@ window.openAIChatManager = function () {
|
|
|
2533
2431
|
console.error('an element with the class chat-session-history-item with no data-session-id set.');
|
|
2534
2432
|
return;
|
|
2535
2433
|
}
|
|
2536
|
-
|
|
2537
|
-
|
|
2434
|
+
_this21.loadSession(sessionId);
|
|
2435
|
+
_this21.showChatScreen();
|
|
2538
2436
|
});
|
|
2539
2437
|
}
|
|
2540
2438
|
for (var _i5 = 0; _i5 < config.messages.length; _i5++) {
|
|
@@ -2543,7 +2441,7 @@ window.openAIChatManager = function () {
|
|
|
2543
2441
|
|
|
2544
2442
|
// Update feedback icons in the DOM after initial messages have rendered.
|
|
2545
2443
|
this.$nextTick(function () {
|
|
2546
|
-
|
|
2444
|
+
_this21.refreshAllFeedbackIcons();
|
|
2547
2445
|
});
|
|
2548
2446
|
|
|
2549
2447
|
// Delegate click for code block copy buttons.
|
|
@@ -2575,7 +2473,7 @@ window.openAIChatManager = function () {
|
|
|
2575
2473
|
if (this.micButton) {
|
|
2576
2474
|
this.micButton.style.display = '';
|
|
2577
2475
|
this.micButton.addEventListener('click', function () {
|
|
2578
|
-
|
|
2476
|
+
_this21.toggleRecording();
|
|
2579
2477
|
});
|
|
2580
2478
|
}
|
|
2581
2479
|
}
|
|
@@ -2585,10 +2483,11 @@ window.openAIChatManager = function () {
|
|
|
2585
2483
|
this.conversationButton = document.querySelector(config.conversationButtonElementSelector);
|
|
2586
2484
|
if (this.conversationButton) {
|
|
2587
2485
|
this.conversationButton.addEventListener('click', function () {
|
|
2588
|
-
|
|
2486
|
+
_this21.toggleConversationMode();
|
|
2589
2487
|
});
|
|
2590
2488
|
}
|
|
2591
2489
|
}
|
|
2490
|
+
return true;
|
|
2592
2491
|
},
|
|
2593
2492
|
loadSession: function loadSession(sessionId) {
|
|
2594
2493
|
this.connection.invoke("LoadSession", sessionId)["catch"](function (err) {
|
|
@@ -2603,6 +2502,9 @@ window.openAIChatManager = function () {
|
|
|
2603
2502
|
},
|
|
2604
2503
|
initializeSession: function initializeSession(sessionId, force) {
|
|
2605
2504
|
if (this.isSessionStarted && !force) {
|
|
2505
|
+
if (sessionId && this.getSessionId() === sessionId) {
|
|
2506
|
+
this.resolvePendingSessionRequest(sessionId);
|
|
2507
|
+
}
|
|
2606
2508
|
return;
|
|
2607
2509
|
}
|
|
2608
2510
|
this.fireEvent(new CustomEvent("initializingSessionOpenAIChat", {
|
|
@@ -2612,121 +2514,22 @@ window.openAIChatManager = function () {
|
|
|
2612
2514
|
}));
|
|
2613
2515
|
this.setSessionId(sessionId);
|
|
2614
2516
|
this.isSessionStarted = true;
|
|
2615
|
-
|
|
2616
|
-
|
|
2517
|
+
this.resolvePendingSessionRequest(sessionId);
|
|
2518
|
+
if (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {
|
|
2519
|
+
widgetBehavior.onSessionInitialized(this, sessionId, config);
|
|
2617
2520
|
}
|
|
2618
2521
|
},
|
|
2619
|
-
initializeWidget: function initializeWidget() {
|
|
2620
|
-
var _this16 = this;
|
|
2621
|
-
if (!config.widget.chatWidgetContainer) {
|
|
2622
|
-
console.error('The widget chatWidgetContainer is required.');
|
|
2623
|
-
return;
|
|
2624
|
-
}
|
|
2625
|
-
if (!config.widget.chatWidgetStateName) {
|
|
2626
|
-
console.error('The widget chatWidgetStateName is required.');
|
|
2627
|
-
return;
|
|
2628
|
-
}
|
|
2629
|
-
var chatWidgetContainer = document.querySelector(config.widget.chatWidgetContainer);
|
|
2630
|
-
if (!chatWidgetContainer) {
|
|
2631
|
-
return;
|
|
2632
|
-
}
|
|
2633
|
-
if (config.widget.chatHistorySection) {
|
|
2634
|
-
this.chatHistorySection = document.querySelector(config.widget.chatHistorySection);
|
|
2635
|
-
}
|
|
2636
|
-
this.chatWidgetStateName = config.widget.chatWidgetStateName;
|
|
2637
|
-
this.chatWidgetStateSession = config.widget.chatWidgetStateName + 'Session';
|
|
2638
|
-
this.chatWidgetLayoutKey = config.widget.chatWidgetStateName + 'Layout';
|
|
2639
|
-
this.widgetContainerElement = chatWidgetContainer;
|
|
2640
|
-
this.widgetToggleButtonElement = config.widget.toggleButtonSelector ? document.querySelector(config.widget.toggleButtonSelector) : null;
|
|
2641
|
-
this.widgetResetSizeButtonElement = config.widget.resetSizeButtonSelector ? document.querySelector(config.widget.resetSizeButtonSelector) : null;
|
|
2642
|
-
this.widgetDefaultWidth = parsePixelValue(config.widget.defaultWidth) || parsePixelValue(window.getComputedStyle(chatWidgetContainer).width) || 380;
|
|
2643
|
-
this.widgetDefaultHeight = parsePixelValue(config.widget.defaultHeight) || parsePixelValue(window.getComputedStyle(chatWidgetContainer).height) || 520;
|
|
2644
|
-
this.widgetIsInitialized = true;
|
|
2645
|
-
if (config.widget.enableResizing) {
|
|
2646
|
-
chatWidgetContainer.classList.add('ai-chat-widget-resizable');
|
|
2647
|
-
chatWidgetContainer.style.minWidth = (parsePixelValue(config.widget.minWidth) || 320) + 'px';
|
|
2648
|
-
chatWidgetContainer.style.minHeight = (parsePixelValue(config.widget.minHeight) || 420) + 'px';
|
|
2649
|
-
if (typeof ResizeObserver !== 'undefined') {
|
|
2650
|
-
this.widgetResizeObserver = new ResizeObserver(function () {
|
|
2651
|
-
_this16.persistWidgetPanelSize();
|
|
2652
|
-
_this16.constrainWidgetElementsToViewport();
|
|
2653
|
-
_this16.updateWidgetResetSizeButtonVisibility();
|
|
2654
|
-
});
|
|
2655
|
-
this.widgetResizeObserver.observe(chatWidgetContainer);
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
var dragHandleSelector = config.widget.dragHandleSelector || '.ai-chat-widget-header';
|
|
2659
|
-
var dragHandle = chatWidgetContainer.querySelector(dragHandleSelector);
|
|
2660
|
-
if (config.widget.enableDragging && dragHandle) {
|
|
2661
|
-
dragHandle.classList.add('ai-chat-widget-drag-handle');
|
|
2662
|
-
chatWidgetContainer.classList.add('ai-chat-widget-draggable');
|
|
2663
|
-
this.attachDraggableWidgetElement(chatWidgetContainer, dragHandle, 'panel', false);
|
|
2664
|
-
}
|
|
2665
|
-
if (config.widget.enableDragging && this.widgetToggleButtonElement) {
|
|
2666
|
-
this.widgetToggleButtonElement.classList.add('ai-chat-widget-draggable');
|
|
2667
|
-
this.attachDraggableWidgetElement(this.widgetToggleButtonElement, this.widgetToggleButtonElement, 'toggle', true);
|
|
2668
|
-
}
|
|
2669
|
-
if (this.widgetResetSizeButtonElement) {
|
|
2670
|
-
this.widgetResetSizeButtonElement.addEventListener('click', function (event) {
|
|
2671
|
-
event.preventDefault();
|
|
2672
|
-
_this16.resetWidgetSize();
|
|
2673
|
-
});
|
|
2674
|
-
}
|
|
2675
|
-
this.restoreWidgetLayout();
|
|
2676
|
-
if (!this.widgetViewportResizeHandler) {
|
|
2677
|
-
this.widgetViewportResizeHandler = function () {
|
|
2678
|
-
_this16.constrainWidgetElementsToViewport();
|
|
2679
|
-
_this16.updateWidgetResetSizeButtonVisibility();
|
|
2680
|
-
};
|
|
2681
|
-
window.addEventListener('resize', this.widgetViewportResizeHandler);
|
|
2682
|
-
}
|
|
2683
|
-
|
|
2684
|
-
// Auto-load the last session so the user always sees previous chat history.
|
|
2685
|
-
this.reloadCurrentSession();
|
|
2686
|
-
if (config.autoCreateSession && !this.getSessionId()) {
|
|
2687
|
-
this.startNewSession();
|
|
2688
|
-
}
|
|
2689
|
-
if (config.widget.showHistoryButton && this.chatHistorySection) {
|
|
2690
|
-
var showHistoryButton = document.querySelector(config.widget.showHistoryButton);
|
|
2691
|
-
if (showHistoryButton) {
|
|
2692
|
-
showHistoryButton.addEventListener('click', function () {
|
|
2693
|
-
_this16.chatHistorySection.classList.toggle('show');
|
|
2694
|
-
});
|
|
2695
|
-
}
|
|
2696
|
-
if (config.widget.closeHistoryButton) {
|
|
2697
|
-
var closeHistoryButton = document.querySelector(config.widget.closeHistoryButton);
|
|
2698
|
-
if (closeHistoryButton) {
|
|
2699
|
-
closeHistoryButton.addEventListener('click', function () {
|
|
2700
|
-
_this16.showChatScreen();
|
|
2701
|
-
});
|
|
2702
|
-
}
|
|
2703
|
-
}
|
|
2704
|
-
}
|
|
2705
|
-
if (config.widget.newChatButton) {
|
|
2706
|
-
var newChatButton = document.querySelector(config.widget.newChatButton);
|
|
2707
|
-
if (newChatButton) {
|
|
2708
|
-
newChatButton.addEventListener('click', function () {
|
|
2709
|
-
_this16.resetSession();
|
|
2710
|
-
_this16.showChatScreen();
|
|
2711
|
-
});
|
|
2712
|
-
}
|
|
2713
|
-
}
|
|
2714
|
-
},
|
|
2715
|
-
showChatScreen: function showChatScreen() {
|
|
2716
|
-
if (!this.chatHistorySection) {
|
|
2717
|
-
return;
|
|
2718
|
-
}
|
|
2719
|
-
this.chatHistorySection.classList.remove('show');
|
|
2720
|
-
},
|
|
2721
2522
|
getSessionId: function getSessionId() {
|
|
2722
|
-
var sessionId = this.inputElement.getAttribute('data-session-id');
|
|
2723
|
-
if (!sessionId &&
|
|
2724
|
-
sessionId =
|
|
2523
|
+
var sessionId = this.inputElement ? this.inputElement.getAttribute('data-session-id') : null;
|
|
2524
|
+
if (!sessionId && widgetBehavior && typeof widgetBehavior.resolveSessionId === 'function') {
|
|
2525
|
+
sessionId = widgetBehavior.resolveSessionId(this, config);
|
|
2725
2526
|
}
|
|
2726
2527
|
return sessionId;
|
|
2727
2528
|
},
|
|
2728
2529
|
copyResponse: function copyResponse(message) {
|
|
2729
|
-
|
|
2530
|
+
var _ref17, _message$copyContent;
|
|
2531
|
+
var text = message && _typeof(message) === 'object' ? (_ref17 = (_message$copyContent = message.copyContent) !== null && _message$copyContent !== void 0 ? _message$copyContent : message.content) !== null && _ref17 !== void 0 ? _ref17 : '' : message !== null && message !== void 0 ? message : '';
|
|
2532
|
+
navigator.clipboard.writeText(text);
|
|
2730
2533
|
},
|
|
2731
2534
|
updateFeedbackIcons: function updateFeedbackIcons(container, userRating) {
|
|
2732
2535
|
if (!container) {
|
|
@@ -2735,11 +2538,11 @@ window.openAIChatManager = function () {
|
|
|
2735
2538
|
var upBtn = container.querySelector('.rate-up-btn');
|
|
2736
2539
|
var downBtn = container.querySelector('.rate-down-btn');
|
|
2737
2540
|
|
|
2738
|
-
//
|
|
2739
|
-
//
|
|
2541
|
+
// Keep feedback icons as simple span-based Font Awesome markup so
|
|
2542
|
+
// later state updates do not depend on i2svg replacement.
|
|
2740
2543
|
if (upBtn) {
|
|
2741
2544
|
var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';
|
|
2742
|
-
var upIcon = document.createElement('
|
|
2545
|
+
var upIcon = document.createElement('span');
|
|
2743
2546
|
upIcon.className = upClass;
|
|
2744
2547
|
upIcon.style.fontSize = '0.9rem';
|
|
2745
2548
|
upBtn.textContent = '';
|
|
@@ -2747,19 +2550,12 @@ window.openAIChatManager = function () {
|
|
|
2747
2550
|
}
|
|
2748
2551
|
if (downBtn) {
|
|
2749
2552
|
var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';
|
|
2750
|
-
var downIcon = document.createElement('
|
|
2553
|
+
var downIcon = document.createElement('span');
|
|
2751
2554
|
downIcon.className = downClass;
|
|
2752
2555
|
downIcon.style.fontSize = '0.9rem';
|
|
2753
2556
|
downBtn.textContent = '';
|
|
2754
2557
|
downBtn.appendChild(downIcon);
|
|
2755
2558
|
}
|
|
2756
|
-
|
|
2757
|
-
// Trigger Font Awesome SVG+JS to convert the new <i> elements.
|
|
2758
|
-
if (window.FontAwesome && FontAwesome.dom && FontAwesome.dom.i2svg) {
|
|
2759
|
-
FontAwesome.dom.i2svg({
|
|
2760
|
-
node: container
|
|
2761
|
-
});
|
|
2762
|
-
}
|
|
2763
2559
|
},
|
|
2764
2560
|
refreshAllFeedbackIcons: function refreshAllFeedbackIcons() {
|
|
2765
2561
|
var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');
|
|
@@ -2812,12 +2608,18 @@ window.openAIChatManager = function () {
|
|
|
2812
2608
|
documents: {
|
|
2813
2609
|
handler: function handler() {
|
|
2814
2610
|
this.renderDocumentBar();
|
|
2611
|
+
if (widgetBehavior && typeof widgetBehavior.onDocumentsChanged === 'function') {
|
|
2612
|
+
widgetBehavior.onDocumentsChanged(this, this.documents, config);
|
|
2613
|
+
}
|
|
2815
2614
|
},
|
|
2816
2615
|
deep: true
|
|
2817
2616
|
},
|
|
2818
2617
|
isUploading: function isUploading() {
|
|
2819
2618
|
this.renderDocumentBar();
|
|
2820
2619
|
},
|
|
2620
|
+
isDocumentOperationPending: function isDocumentOperationPending() {
|
|
2621
|
+
this.renderDocumentBar();
|
|
2622
|
+
},
|
|
2821
2623
|
isPlayingAudio: function isPlayingAudio() {
|
|
2822
2624
|
// Reserved for future use — volume-based interrupt detection
|
|
2823
2625
|
// no longer mutes tracks; browser echo cancellation handles echo.
|
|
@@ -2843,22 +2645,27 @@ window.openAIChatManager = function () {
|
|
|
2843
2645
|
}
|
|
2844
2646
|
},
|
|
2845
2647
|
mounted: function mounted() {
|
|
2846
|
-
var
|
|
2847
|
-
_asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
2848
|
-
|
|
2849
|
-
|
|
2648
|
+
var _this22 = this;
|
|
2649
|
+
_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0() {
|
|
2650
|
+
var isInitialized;
|
|
2651
|
+
return _regenerator().w(function (_context0) {
|
|
2652
|
+
while (1) switch (_context0.n) {
|
|
2850
2653
|
case 0:
|
|
2851
|
-
|
|
2852
|
-
return
|
|
2654
|
+
_context0.n = 1;
|
|
2655
|
+
return _this22.startConnection();
|
|
2853
2656
|
case 1:
|
|
2854
|
-
|
|
2855
|
-
if (hasWidgetConfig) {
|
|
2856
|
-
|
|
2657
|
+
isInitialized = _this22.initializeApp();
|
|
2658
|
+
if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {
|
|
2659
|
+
widgetBehavior.onMounted(_this22, config);
|
|
2857
2660
|
}
|
|
2661
|
+
_this22.$nextTick(function () {
|
|
2662
|
+
refreshFontAwesomeIcons(_this22.$el);
|
|
2663
|
+
_this22.fontAwesomeObserver = observeFontAwesomeIcons(_this22.$el);
|
|
2664
|
+
});
|
|
2858
2665
|
case 2:
|
|
2859
|
-
return
|
|
2666
|
+
return _context0.a(2);
|
|
2860
2667
|
}
|
|
2861
|
-
},
|
|
2668
|
+
}, _callee0);
|
|
2862
2669
|
}))();
|
|
2863
2670
|
window.addEventListener('beforeunload', this.handleBeforeUnload);
|
|
2864
2671
|
window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);
|
|
@@ -2866,6 +2673,10 @@ window.openAIChatManager = function () {
|
|
|
2866
2673
|
beforeUnmount: function beforeUnmount() {
|
|
2867
2674
|
window.removeEventListener('beforeunload', this.handleBeforeUnload);
|
|
2868
2675
|
window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);
|
|
2676
|
+
if (this.fontAwesomeObserver) {
|
|
2677
|
+
this.fontAwesomeObserver.disconnect();
|
|
2678
|
+
this.fontAwesomeObserver = null;
|
|
2679
|
+
}
|
|
2869
2680
|
this.stopAudio(false);
|
|
2870
2681
|
if (this.stream) {
|
|
2871
2682
|
this.stream.dispose();
|
|
@@ -2874,9 +2685,16 @@ window.openAIChatManager = function () {
|
|
|
2874
2685
|
if (this.connection) {
|
|
2875
2686
|
this.connection.stop();
|
|
2876
2687
|
}
|
|
2688
|
+
if (widgetBehavior && typeof widgetBehavior.onBeforeUnmount === 'function') {
|
|
2689
|
+
widgetBehavior.onBeforeUnmount(this, config);
|
|
2690
|
+
}
|
|
2877
2691
|
},
|
|
2878
2692
|
template: config.messageTemplate
|
|
2879
|
-
}
|
|
2693
|
+
};
|
|
2694
|
+
var app = Vue.createApp(appDefinition).mount(config.appElementSelector);
|
|
2695
|
+
if (widgetBehavior && typeof widgetBehavior.attach === 'function') {
|
|
2696
|
+
widgetBehavior.attach(app, config);
|
|
2697
|
+
}
|
|
2880
2698
|
return app;
|
|
2881
2699
|
};
|
|
2882
2700
|
return {
|