@crestapps/ai-chat-ui 1.0.0-preview.7 → 1.0.0-preview.73
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 +814 -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 +380 -0
- package/dist/ai-chat.css.map +1 -0
- package/dist/ai-chat.js +861 -966
- package/dist/ai-chat.js.map +1 -1
- package/dist/ai-chat.min.css +1 -0
- package/dist/ai-chat.min.js +1 -1
- package/dist/ai-chat.min.js.map +1 -1
- package/dist/chat-interaction-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 +106 -3
- 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 +12 -1
- package/README.md +0 -145
package/dist/chat-interaction.js
CHANGED
|
@@ -3,22 +3,25 @@
|
|
|
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
|
-
|
|
7
|
-
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."); }
|
|
8
|
-
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
9
|
-
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
10
|
-
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
6
|
+
var _excluded = ["placeholder"];
|
|
11
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 }; })(); }
|
|
12
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); }
|
|
13
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); }
|
|
14
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); }); }; }
|
|
15
|
-
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; } } }; }
|
|
16
11
|
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
17
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."); }
|
|
18
|
-
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; } }
|
|
19
13
|
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
20
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; } } }; }
|
|
18
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
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."); }
|
|
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; } }
|
|
21
21
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
22
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
23
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
24
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
22
25
|
window.chatInteractionManager = function () {
|
|
23
26
|
// Defaults (can be overridden by instanceConfig)
|
|
24
27
|
var defaultConfig = {
|
|
@@ -30,7 +33,7 @@ window.chatInteractionManager = function () {
|
|
|
30
33
|
downloadChartButtonText: 'Download',
|
|
31
34
|
codeCopiedText: 'Copied!',
|
|
32
35
|
assistantLabel: 'Assistant',
|
|
33
|
-
messageTemplate: "\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"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\">You</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 <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
|
|
36
|
+
messageTemplate: "\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"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\">You</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 <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=\"Click here to copy response to clipboard.\">\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 ",
|
|
34
37
|
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 ",
|
|
35
38
|
// Localizable strings
|
|
36
39
|
untitledText: 'Untitled',
|
|
@@ -56,6 +59,200 @@ window.chatInteractionManager = function () {
|
|
|
56
59
|
span.textContent = text;
|
|
57
60
|
return span.innerHTML;
|
|
58
61
|
}
|
|
62
|
+
function containsFontAwesomePlaceholders(root) {
|
|
63
|
+
if (!root || root.nodeType !== 1) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
var selector = 'i[class*="fa-"],i.fa,i.fas,i.far,i.fab';
|
|
67
|
+
if (typeof root.matches === 'function' && root.matches(selector)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
return typeof root.querySelector === 'function' && !!root.querySelector(selector);
|
|
71
|
+
}
|
|
72
|
+
function refreshFontAwesomeIcons(root) {
|
|
73
|
+
var fontAwesome = window.FontAwesome;
|
|
74
|
+
if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
fontAwesome.dom.i2svg({
|
|
78
|
+
node: root
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function observeFontAwesomeIcons(root) {
|
|
82
|
+
if (!root || typeof MutationObserver === 'undefined') {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
var observer = new MutationObserver(function (mutations) {
|
|
86
|
+
mutations.forEach(function (mutation) {
|
|
87
|
+
mutation.addedNodes.forEach(function (node) {
|
|
88
|
+
refreshFontAwesomeIcons(node);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
observer.observe(root, {
|
|
93
|
+
childList: true,
|
|
94
|
+
subtree: true
|
|
95
|
+
});
|
|
96
|
+
return observer;
|
|
97
|
+
}
|
|
98
|
+
function normalizeReference(reference) {
|
|
99
|
+
var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$title, _ref4, _normalized$link, _ref5, _normalized$reference;
|
|
100
|
+
if (!reference || _typeof(reference) !== 'object') {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
var normalized = Object.assign({}, reference);
|
|
104
|
+
normalized.index = (_ref = (_normalized$index = normalized.index) !== null && _normalized$index !== void 0 ? _normalized$index : normalized.Index) !== null && _ref !== void 0 ? _ref : 0;
|
|
105
|
+
normalized.text = (_ref2 = (_normalized$text = normalized.text) !== null && _normalized$text !== void 0 ? _normalized$text : normalized.Text) !== null && _ref2 !== void 0 ? _ref2 : null;
|
|
106
|
+
normalized.title = (_ref3 = (_normalized$title = normalized.title) !== null && _normalized$title !== void 0 ? _normalized$title : normalized.Title) !== null && _ref3 !== void 0 ? _ref3 : null;
|
|
107
|
+
normalized.link = sanitizeUrl((_ref4 = (_normalized$link = normalized.link) !== null && _normalized$link !== void 0 ? _normalized$link : normalized.Link) !== null && _ref4 !== void 0 ? _ref4 : null);
|
|
108
|
+
normalized.referenceType = (_ref5 = (_normalized$reference = normalized.referenceType) !== null && _normalized$reference !== void 0 ? _normalized$reference : normalized.ReferenceType) !== null && _ref5 !== void 0 ? _ref5 : null;
|
|
109
|
+
return normalized;
|
|
110
|
+
}
|
|
111
|
+
function isDownloadCitationReference(reference) {
|
|
112
|
+
if (!reference || _typeof(reference) !== 'object') {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
if (typeof reference.referenceType === 'string' && reference.referenceType.toLowerCase() === 'document') {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
if (typeof reference.link === 'string' && /\/ai\/documents\/.+\/download(?:$|\?)/i.test(reference.link)) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
function normalizeReferences(references) {
|
|
124
|
+
if (!references || _typeof(references) !== 'object') {
|
|
125
|
+
return {};
|
|
126
|
+
}
|
|
127
|
+
var normalized = {};
|
|
128
|
+
for (var _i = 0, _Object$entries = Object.entries(references); _i < _Object$entries.length; _i++) {
|
|
129
|
+
var _normalizeReference;
|
|
130
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
|
|
131
|
+
key = _Object$entries$_i[0],
|
|
132
|
+
value = _Object$entries$_i[1];
|
|
133
|
+
normalized[key] = (_normalizeReference = normalizeReference(value)) !== null && _normalizeReference !== void 0 ? _normalizeReference : {};
|
|
134
|
+
}
|
|
135
|
+
return normalized;
|
|
136
|
+
}
|
|
137
|
+
function getCitationLabel(reference, key) {
|
|
138
|
+
return reference.title || reference.text || key;
|
|
139
|
+
}
|
|
140
|
+
function buildCitationDisplay(content, references) {
|
|
141
|
+
var processedContent = (content || '').trim();
|
|
142
|
+
var messageReferences = normalizeReferences(references);
|
|
143
|
+
if (!processedContent || !Object.keys(messageReferences).length) {
|
|
144
|
+
return {
|
|
145
|
+
content: processedContent,
|
|
146
|
+
citations: []
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
var citedRefs = Object.entries(messageReferences).filter(function (_ref6) {
|
|
150
|
+
var _ref7 = _slicedToArray(_ref6, 1),
|
|
151
|
+
key = _ref7[0];
|
|
152
|
+
return processedContent.includes(key);
|
|
153
|
+
});
|
|
154
|
+
if (!citedRefs.length) {
|
|
155
|
+
return {
|
|
156
|
+
content: processedContent,
|
|
157
|
+
citations: []
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
citedRefs.sort(function (_ref8, _ref9) {
|
|
161
|
+
var _ref0 = _slicedToArray(_ref8, 2),
|
|
162
|
+
a = _ref0[1];
|
|
163
|
+
var _ref1 = _slicedToArray(_ref9, 2),
|
|
164
|
+
b = _ref1[1];
|
|
165
|
+
return a.index - b.index;
|
|
166
|
+
});
|
|
167
|
+
var citations = [];
|
|
168
|
+
var displayIndex = 1;
|
|
169
|
+
var _iterator = _createForOfIteratorHelper(citedRefs),
|
|
170
|
+
_step;
|
|
171
|
+
try {
|
|
172
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
173
|
+
var _step$value = _slicedToArray(_step.value, 2),
|
|
174
|
+
key = _step$value[0],
|
|
175
|
+
value = _step$value[1];
|
|
176
|
+
var placeholder = "__CITE_".concat(displayIndex, "_").concat(value.index || displayIndex, "__");
|
|
177
|
+
processedContent = processedContent.replaceAll(key, placeholder);
|
|
178
|
+
citations.push({
|
|
179
|
+
referenceKey: key,
|
|
180
|
+
displayIndex: displayIndex,
|
|
181
|
+
label: getCitationLabel(value, key),
|
|
182
|
+
link: value.link || null,
|
|
183
|
+
isDownload: isDownloadCitationReference(value),
|
|
184
|
+
placeholder: placeholder
|
|
185
|
+
});
|
|
186
|
+
displayIndex++;
|
|
187
|
+
}
|
|
188
|
+
} catch (err) {
|
|
189
|
+
_iterator.e(err);
|
|
190
|
+
} finally {
|
|
191
|
+
_iterator.f();
|
|
192
|
+
}
|
|
193
|
+
for (var _i2 = 0, _citations = citations; _i2 < _citations.length; _i2++) {
|
|
194
|
+
var citation = _citations[_i2];
|
|
195
|
+
processedContent = processedContent.replaceAll(citation.placeholder, "<sup>".concat(citation.displayIndex, "</sup>"));
|
|
196
|
+
}
|
|
197
|
+
processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');
|
|
198
|
+
return {
|
|
199
|
+
content: processedContent,
|
|
200
|
+
citations: citations.map(function (_ref10) {
|
|
201
|
+
var placeholder = _ref10.placeholder,
|
|
202
|
+
citation = _objectWithoutProperties(_ref10, _excluded);
|
|
203
|
+
return citation;
|
|
204
|
+
})
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function buildCopyContent(content, citations) {
|
|
208
|
+
var copyContent = (content || '').trim();
|
|
209
|
+
if (!copyContent || !Array.isArray(citations) || citations.length === 0) {
|
|
210
|
+
return copyContent;
|
|
211
|
+
}
|
|
212
|
+
var _iterator2 = _createForOfIteratorHelper(citations),
|
|
213
|
+
_step2;
|
|
214
|
+
try {
|
|
215
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
216
|
+
var citation = _step2.value;
|
|
217
|
+
copyContent = copyContent.replaceAll(citation.referenceKey, "[".concat(citation.displayIndex, "]"));
|
|
218
|
+
}
|
|
219
|
+
} catch (err) {
|
|
220
|
+
_iterator2.e(err);
|
|
221
|
+
} finally {
|
|
222
|
+
_iterator2.f();
|
|
223
|
+
}
|
|
224
|
+
copyContent += '\n\nReferences:\n';
|
|
225
|
+
var _iterator3 = _createForOfIteratorHelper(citations),
|
|
226
|
+
_step3;
|
|
227
|
+
try {
|
|
228
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
229
|
+
var _citation = _step3.value;
|
|
230
|
+
copyContent += "".concat(_citation.displayIndex, ". ").concat(_citation.label);
|
|
231
|
+
if (_citation.link) {
|
|
232
|
+
copyContent += " - ".concat(_citation.link);
|
|
233
|
+
}
|
|
234
|
+
copyContent += '\n';
|
|
235
|
+
}
|
|
236
|
+
} catch (err) {
|
|
237
|
+
_iterator3.e(err);
|
|
238
|
+
} finally {
|
|
239
|
+
_iterator3.f();
|
|
240
|
+
}
|
|
241
|
+
return copyContent.trimEnd();
|
|
242
|
+
}
|
|
243
|
+
function updateMessagePresentation(message, references) {
|
|
244
|
+
var messageReferences = normalizeReferences(references !== null && references !== void 0 ? references : message.references);
|
|
245
|
+
var rawContent = typeof message.rawContent === 'string' ? message.rawContent : typeof message.content === 'string' ? message.content : '';
|
|
246
|
+
var citationDisplay = buildCitationDisplay(rawContent, messageReferences);
|
|
247
|
+
message.rawContent = rawContent;
|
|
248
|
+
message.content = rawContent;
|
|
249
|
+
message.displayContent = citationDisplay.content;
|
|
250
|
+
message.references = messageReferences;
|
|
251
|
+
message.citationReferences = citationDisplay.citations;
|
|
252
|
+
message.copyContent = buildCopyContent(rawContent, citationDisplay.citations);
|
|
253
|
+
message.htmlContent = parseMarkdownContent(citationDisplay.content, message);
|
|
254
|
+
return message;
|
|
255
|
+
}
|
|
59
256
|
var renderer = new marked.Renderer();
|
|
60
257
|
|
|
61
258
|
// Modify the link rendering to open in a new tab
|
|
@@ -219,11 +416,11 @@ window.chatInteractionManager = function () {
|
|
|
219
416
|
// Defer to requestAnimationFrame so the browser has fully laid out the
|
|
220
417
|
// canvas elements before Chart.js reads their dimensions.
|
|
221
418
|
requestAnimationFrame(function () {
|
|
222
|
-
var
|
|
223
|
-
|
|
419
|
+
var _iterator4 = _createForOfIteratorHelper(charts),
|
|
420
|
+
_step4;
|
|
224
421
|
try {
|
|
225
|
-
for (
|
|
226
|
-
var c =
|
|
422
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
423
|
+
var c = _step4.value;
|
|
227
424
|
var canvas = document.getElementById(c.chartId);
|
|
228
425
|
if (!canvas) {
|
|
229
426
|
continue;
|
|
@@ -256,9 +453,9 @@ window.chatInteractionManager = function () {
|
|
|
256
453
|
}
|
|
257
454
|
}
|
|
258
455
|
} catch (err) {
|
|
259
|
-
|
|
456
|
+
_iterator4.e(err);
|
|
260
457
|
} finally {
|
|
261
|
-
|
|
458
|
+
_iterator4.f();
|
|
262
459
|
}
|
|
263
460
|
});
|
|
264
461
|
}
|
|
@@ -467,7 +664,7 @@ window.chatInteractionManager = function () {
|
|
|
467
664
|
_this.scrollToBottom();
|
|
468
665
|
}
|
|
469
666
|
});
|
|
470
|
-
_this.connection.on("ReceiveConversationAssistantToken", function (itemId, messageId, token, responseId, appearance) {
|
|
667
|
+
_this.connection.on("ReceiveConversationAssistantToken", function (itemId, messageId, token, responseId, references, appearance) {
|
|
471
668
|
if (!_this._conversationAssistantMessage) {
|
|
472
669
|
_this.stopAudio();
|
|
473
670
|
_this.hideTypingIndicator();
|
|
@@ -485,7 +682,8 @@ window.chatInteractionManager = function () {
|
|
|
485
682
|
content: "",
|
|
486
683
|
htmlContent: "",
|
|
487
684
|
isStreaming: true,
|
|
488
|
-
appearance: _this.normalizeAssistantAppearance(appearance)
|
|
685
|
+
appearance: _this.normalizeAssistantAppearance(appearance),
|
|
686
|
+
references: {}
|
|
489
687
|
};
|
|
490
688
|
_this.messages.push(newMessage);
|
|
491
689
|
_this._conversationAssistantMessage = {
|
|
@@ -499,19 +697,22 @@ window.chatInteractionManager = function () {
|
|
|
499
697
|
if (!msg.appearance) {
|
|
500
698
|
msg.appearance = _this.normalizeAssistantAppearance(appearance);
|
|
501
699
|
}
|
|
502
|
-
msg.
|
|
503
|
-
msg.
|
|
700
|
+
msg.rawContent = _this._conversationAssistantMessage.content;
|
|
701
|
+
msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));
|
|
702
|
+
updateMessagePresentation(msg, msg.references);
|
|
504
703
|
_this.$nextTick(function () {
|
|
505
704
|
renderChartsInMessage(msg);
|
|
506
705
|
_this.scrollToBottom();
|
|
507
706
|
});
|
|
508
707
|
}
|
|
509
708
|
});
|
|
510
|
-
_this.connection.on("ReceiveConversationAssistantComplete", function (itemId, messageId) {
|
|
709
|
+
_this.connection.on("ReceiveConversationAssistantComplete", function (itemId, messageId, references) {
|
|
511
710
|
if (_this._conversationAssistantMessage) {
|
|
512
711
|
var msg = _this.messages[_this._conversationAssistantMessage.index];
|
|
513
712
|
if (msg) {
|
|
514
713
|
msg.isStreaming = false;
|
|
714
|
+
msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));
|
|
715
|
+
updateMessagePresentation(msg, msg.references);
|
|
515
716
|
}
|
|
516
717
|
_this._conversationAssistantMessage = null;
|
|
517
718
|
}
|
|
@@ -605,79 +806,9 @@ window.chatInteractionManager = function () {
|
|
|
605
806
|
addMessage: function addMessage(message) {
|
|
606
807
|
var _this3 = this;
|
|
607
808
|
if (message.content) {
|
|
608
|
-
var
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
var citedRefs = Object.entries(message.references).filter(function (_ref) {
|
|
612
|
-
var _ref2 = _slicedToArray(_ref, 1),
|
|
613
|
-
key = _ref2[0];
|
|
614
|
-
return processedContent.includes(key);
|
|
615
|
-
});
|
|
616
|
-
if (citedRefs.length) {
|
|
617
|
-
// Sort by original index so display indices follow a natural order.
|
|
618
|
-
citedRefs.sort(function (_ref3, _ref4) {
|
|
619
|
-
var _ref5 = _slicedToArray(_ref3, 2),
|
|
620
|
-
a = _ref5[1];
|
|
621
|
-
var _ref6 = _slicedToArray(_ref4, 2),
|
|
622
|
-
b = _ref6[1];
|
|
623
|
-
return a.index - b.index;
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
// Phase 1: Replace all markers with unique placeholders.
|
|
627
|
-
var displayIndex = 1;
|
|
628
|
-
var _iterator2 = _createForOfIteratorHelper(citedRefs),
|
|
629
|
-
_step2;
|
|
630
|
-
try {
|
|
631
|
-
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
632
|
-
var _step2$value = _slicedToArray(_step2.value, 2),
|
|
633
|
-
key = _step2$value[0],
|
|
634
|
-
value = _step2$value[1];
|
|
635
|
-
var placeholder = "__CITE_".concat(value.index, "__");
|
|
636
|
-
processedContent = processedContent.replaceAll(key, placeholder);
|
|
637
|
-
value._displayIndex = displayIndex++;
|
|
638
|
-
value._placeholder = placeholder;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
// Phase 2: Replace placeholders with sequential display indices.
|
|
642
|
-
} catch (err) {
|
|
643
|
-
_iterator2.e(err);
|
|
644
|
-
} finally {
|
|
645
|
-
_iterator2.f();
|
|
646
|
-
}
|
|
647
|
-
var _iterator3 = _createForOfIteratorHelper(citedRefs),
|
|
648
|
-
_step3;
|
|
649
|
-
try {
|
|
650
|
-
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
651
|
-
var _step3$value = _slicedToArray(_step3.value, 2),
|
|
652
|
-
_value = _step3$value[1];
|
|
653
|
-
processedContent = processedContent.replaceAll(_value._placeholder, "<sup><strong>".concat(_value._displayIndex, "</strong></sup>"));
|
|
654
|
-
}
|
|
655
|
-
} catch (err) {
|
|
656
|
-
_iterator3.e(err);
|
|
657
|
-
} finally {
|
|
658
|
-
_iterator3.f();
|
|
659
|
-
}
|
|
660
|
-
processedContent = processedContent.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');
|
|
661
|
-
processedContent += '<br><br>';
|
|
662
|
-
var _iterator4 = _createForOfIteratorHelper(citedRefs),
|
|
663
|
-
_step4;
|
|
664
|
-
try {
|
|
665
|
-
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
666
|
-
var _step4$value = _slicedToArray(_step4.value, 2),
|
|
667
|
-
_key = _step4$value[0],
|
|
668
|
-
_value2 = _step4$value[1];
|
|
669
|
-
var label = _value2.text || "[doc:".concat(_value2.index, "]");
|
|
670
|
-
processedContent += _value2.link ? "**".concat(_value2._displayIndex, "**. [").concat(label, "](").concat(_value2.link, ")<br>") : "**".concat(_value2._displayIndex, "**. ").concat(label, "<br>");
|
|
671
|
-
}
|
|
672
|
-
} catch (err) {
|
|
673
|
-
_iterator4.e(err);
|
|
674
|
-
} finally {
|
|
675
|
-
_iterator4.f();
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
message.content = processedContent;
|
|
680
|
-
message.htmlContent = parseMarkdownContent(processedContent, message);
|
|
809
|
+
var _message$rawContent;
|
|
810
|
+
message.rawContent = (_message$rawContent = message.rawContent) !== null && _message$rawContent !== void 0 ? _message$rawContent : message.content;
|
|
811
|
+
updateMessagePresentation(message, message.references);
|
|
681
812
|
}
|
|
682
813
|
this.addMessageInternal(message);
|
|
683
814
|
this.hidePlaceholder();
|
|
@@ -828,11 +959,12 @@ window.chatInteractionManager = function () {
|
|
|
828
959
|
message = newMessage;
|
|
829
960
|
}
|
|
830
961
|
if (chunk.references && _typeof(chunk.references) === "object" && Object.keys(chunk.references).length) {
|
|
831
|
-
for (var
|
|
832
|
-
var
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
962
|
+
for (var _i3 = 0, _Object$entries2 = Object.entries(chunk.references); _i3 < _Object$entries2.length; _i3++) {
|
|
963
|
+
var _normalizeReference2;
|
|
964
|
+
var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i3], 2),
|
|
965
|
+
key = _Object$entries2$_i[0],
|
|
966
|
+
value = _Object$entries2$_i[1];
|
|
967
|
+
references[key] = (_normalizeReference2 = normalizeReference(value)) !== null && _normalizeReference2 !== void 0 ? _normalizeReference2 : {};
|
|
836
968
|
}
|
|
837
969
|
}
|
|
838
970
|
if (chunk.content) {
|
|
@@ -844,17 +976,10 @@ window.chatInteractionManager = function () {
|
|
|
844
976
|
if (chunk.responseId) {
|
|
845
977
|
lastResponseId = chunk.responseId;
|
|
846
978
|
}
|
|
847
|
-
|
|
848
|
-
for (var _i2 = 0, _Object$entries2 = Object.entries(references); _i2 < _Object$entries2.length; _i2++) {
|
|
849
|
-
var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2),
|
|
850
|
-
_key2 = _Object$entries2$_i[0],
|
|
851
|
-
_value3 = _Object$entries2$_i[1];
|
|
852
|
-
processedContent = processedContent.replaceAll(_key2, "<sup><strong>".concat(_value3.index, "</strong></sup>"));
|
|
853
|
-
}
|
|
854
|
-
content += processedContent.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');
|
|
979
|
+
content += chunk.content;
|
|
855
980
|
}
|
|
856
|
-
message.
|
|
857
|
-
message
|
|
981
|
+
message.rawContent = content;
|
|
982
|
+
updateMessagePresentation(message, references);
|
|
858
983
|
_this5.messages[messageIndex] = message;
|
|
859
984
|
_this5.$nextTick(function () {
|
|
860
985
|
renderChartsInMessage(message);
|
|
@@ -908,86 +1033,12 @@ window.chatInteractionManager = function () {
|
|
|
908
1033
|
},
|
|
909
1034
|
processReferences: function processReferences(references, messageIndex) {
|
|
910
1035
|
var _this6 = this;
|
|
1036
|
+
references = normalizeReferences(references);
|
|
911
1037
|
if (Object.keys(references).length) {
|
|
1038
|
+
var _ref11, _message$rawContent2;
|
|
912
1039
|
var message = this.messages[messageIndex];
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
// Only include references that were actually cited in the response.
|
|
916
|
-
// Check both raw [doc:N] markers and already-rendered <sup> tags from streaming.
|
|
917
|
-
var citedRefs = Object.entries(references).filter(function (_ref7) {
|
|
918
|
-
var _ref8 = _slicedToArray(_ref7, 2),
|
|
919
|
-
key = _ref8[0],
|
|
920
|
-
value = _ref8[1];
|
|
921
|
-
return content.includes(key) || content.includes("<sup><strong>".concat(value.index, "</strong></sup>"));
|
|
922
|
-
});
|
|
923
|
-
if (!citedRefs.length) {
|
|
924
|
-
return;
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
// Sort by original index so display indices follow a natural order.
|
|
928
|
-
citedRefs.sort(function (_ref9, _ref0) {
|
|
929
|
-
var _ref1 = _slicedToArray(_ref9, 2),
|
|
930
|
-
a = _ref1[1];
|
|
931
|
-
var _ref10 = _slicedToArray(_ref0, 2),
|
|
932
|
-
b = _ref10[1];
|
|
933
|
-
return a.index - b.index;
|
|
934
|
-
});
|
|
935
|
-
|
|
936
|
-
// Phase 1: Replace all markers with unique placeholders to avoid collisions during remapping.
|
|
937
|
-
var processed = content.trim();
|
|
938
|
-
var displayIndex = 1;
|
|
939
|
-
var _iterator5 = _createForOfIteratorHelper(citedRefs),
|
|
940
|
-
_step5;
|
|
941
|
-
try {
|
|
942
|
-
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
943
|
-
var _step5$value = _slicedToArray(_step5.value, 2),
|
|
944
|
-
key = _step5$value[0],
|
|
945
|
-
value = _step5$value[1];
|
|
946
|
-
var placeholder = "__CITE_".concat(value.index, "__");
|
|
947
|
-
processed = processed.replaceAll(key, placeholder);
|
|
948
|
-
processed = processed.replaceAll("<sup><strong>".concat(value.index, "</strong></sup>"), placeholder);
|
|
949
|
-
value._displayIndex = displayIndex++;
|
|
950
|
-
value._placeholder = placeholder;
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
// Phase 2: Replace placeholders with sequential display indices.
|
|
954
|
-
} catch (err) {
|
|
955
|
-
_iterator5.e(err);
|
|
956
|
-
} finally {
|
|
957
|
-
_iterator5.f();
|
|
958
|
-
}
|
|
959
|
-
var _iterator6 = _createForOfIteratorHelper(citedRefs),
|
|
960
|
-
_step6;
|
|
961
|
-
try {
|
|
962
|
-
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
963
|
-
var _step6$value = _slicedToArray(_step6.value, 2),
|
|
964
|
-
_value4 = _step6$value[1];
|
|
965
|
-
processed = processed.replaceAll(_value4._placeholder, "<sup><strong>".concat(_value4._displayIndex, "</strong></sup>"));
|
|
966
|
-
}
|
|
967
|
-
} catch (err) {
|
|
968
|
-
_iterator6.e(err);
|
|
969
|
-
} finally {
|
|
970
|
-
_iterator6.f();
|
|
971
|
-
}
|
|
972
|
-
processed = processed.replaceAll('</strong></sup><sup>', '</strong></sup><sup>,</sup><sup>');
|
|
973
|
-
processed += '<br><br>';
|
|
974
|
-
var _iterator7 = _createForOfIteratorHelper(citedRefs),
|
|
975
|
-
_step7;
|
|
976
|
-
try {
|
|
977
|
-
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
978
|
-
var _step7$value = _slicedToArray(_step7.value, 2),
|
|
979
|
-
_key3 = _step7$value[0],
|
|
980
|
-
_value5 = _step7$value[1];
|
|
981
|
-
var label = _value5.text || "[doc:".concat(_value5.index, "]");
|
|
982
|
-
processed += _value5.link ? "**".concat(_value5._displayIndex, "**. [").concat(label, "](").concat(_value5.link, ")<br>") : "**".concat(_value5._displayIndex, "**. ").concat(label, "<br>");
|
|
983
|
-
}
|
|
984
|
-
} catch (err) {
|
|
985
|
-
_iterator7.e(err);
|
|
986
|
-
} finally {
|
|
987
|
-
_iterator7.f();
|
|
988
|
-
}
|
|
989
|
-
message.content = processed;
|
|
990
|
-
message.htmlContent = parseMarkdownContent(processed, message);
|
|
1040
|
+
message.rawContent = (_ref11 = (_message$rawContent2 = message.rawContent) !== null && _message$rawContent2 !== void 0 ? _message$rawContent2 : message.content) !== null && _ref11 !== void 0 ? _ref11 : '';
|
|
1041
|
+
updateMessagePresentation(message, references);
|
|
991
1042
|
this.messages[messageIndex] = message;
|
|
992
1043
|
this.$nextTick(function () {
|
|
993
1044
|
renderChartsInMessage(message);
|
|
@@ -1039,8 +1090,25 @@ window.chatInteractionManager = function () {
|
|
|
1039
1090
|
}
|
|
1040
1091
|
this.stopAudio(false);
|
|
1041
1092
|
},
|
|
1042
|
-
|
|
1093
|
+
updateTtsPlaybackButtons: function updateTtsPlaybackButtons() {
|
|
1043
1094
|
var _this7 = this;
|
|
1095
|
+
if (!this.chatContainer) {
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
var buttons = this.chatContainer.querySelectorAll('[data-tts-message-index]');
|
|
1099
|
+
buttons.forEach(function (button) {
|
|
1100
|
+
var buttonIndex = Number(button.getAttribute('data-tts-message-index'));
|
|
1101
|
+
var isPlaying = buttonIndex === _this7.ttsPlayingMessageIndex;
|
|
1102
|
+
var iconHtml = isPlaying ? '<i class="fa-solid fa-circle-pause"></i>' : '<i class="fa-solid fa-circle-play"></i>';
|
|
1103
|
+
button.classList.toggle('tts-playing', isPlaying);
|
|
1104
|
+
button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');
|
|
1105
|
+
button.replaceChildren(DOMPurify.sanitize(iconHtml, {
|
|
1106
|
+
RETURN_DOM_FRAGMENT: true
|
|
1107
|
+
}));
|
|
1108
|
+
});
|
|
1109
|
+
},
|
|
1110
|
+
synthesizeSpeech: function synthesizeSpeech(text, cacheIndex) {
|
|
1111
|
+
var _this8 = this;
|
|
1044
1112
|
if (!this.textToSpeechEnabled || !text || !this.connection) {
|
|
1045
1113
|
return;
|
|
1046
1114
|
}
|
|
@@ -1049,12 +1117,16 @@ window.chatInteractionManager = function () {
|
|
|
1049
1117
|
this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;
|
|
1050
1118
|
this.connection.invoke("SynthesizeSpeech", this.getItemId(), text, this.ttsVoiceName)["catch"](function (err) {
|
|
1051
1119
|
console.error("TTS synthesis error:", err);
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1120
|
+
_this8.isPlayingAudio = false;
|
|
1121
|
+
_this8.ttsPlayingMessageIndex = -1;
|
|
1122
|
+
_this8._ttsCacheIndex = -1;
|
|
1123
|
+
_this8.$nextTick(function () {
|
|
1124
|
+
return _this8.updateTtsPlaybackButtons();
|
|
1125
|
+
});
|
|
1055
1126
|
});
|
|
1056
1127
|
},
|
|
1057
1128
|
toggleMessageTts: function toggleMessageTts(message, index) {
|
|
1129
|
+
var _this9 = this;
|
|
1058
1130
|
if (this.ttsPlayingMessageIndex === index) {
|
|
1059
1131
|
this.stopAudio();
|
|
1060
1132
|
return;
|
|
@@ -1066,6 +1138,9 @@ window.chatInteractionManager = function () {
|
|
|
1066
1138
|
}
|
|
1067
1139
|
}));
|
|
1068
1140
|
this.ttsPlayingMessageIndex = index;
|
|
1141
|
+
this.$nextTick(function () {
|
|
1142
|
+
return _this9.updateTtsPlaybackButtons();
|
|
1143
|
+
});
|
|
1069
1144
|
if (this.ttsAudioCache[index]) {
|
|
1070
1145
|
this.playAudioBlob(this.ttsAudioCache[index]);
|
|
1071
1146
|
return;
|
|
@@ -1073,10 +1148,14 @@ window.chatInteractionManager = function () {
|
|
|
1073
1148
|
this.synthesizeSpeech(message.content, index);
|
|
1074
1149
|
},
|
|
1075
1150
|
playCollectedAudio: function playCollectedAudio() {
|
|
1151
|
+
var _this0 = this;
|
|
1076
1152
|
if (this.audioChunks.length === 0) {
|
|
1077
1153
|
if (!this.isPlayingAudio && this.audioPlayQueue.length === 0) {
|
|
1078
1154
|
this.isPlayingAudio = false;
|
|
1079
1155
|
this.ttsPlayingMessageIndex = -1;
|
|
1156
|
+
this.$nextTick(function () {
|
|
1157
|
+
return _this0.updateTtsPlaybackButtons();
|
|
1158
|
+
});
|
|
1080
1159
|
}
|
|
1081
1160
|
return;
|
|
1082
1161
|
}
|
|
@@ -1085,18 +1164,18 @@ window.chatInteractionManager = function () {
|
|
|
1085
1164
|
}, 0);
|
|
1086
1165
|
var combined = new Uint8Array(totalLength);
|
|
1087
1166
|
var offset = 0;
|
|
1088
|
-
var
|
|
1089
|
-
|
|
1167
|
+
var _iterator5 = _createForOfIteratorHelper(this.audioChunks),
|
|
1168
|
+
_step5;
|
|
1090
1169
|
try {
|
|
1091
|
-
for (
|
|
1092
|
-
var chunk =
|
|
1170
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
1171
|
+
var chunk = _step5.value;
|
|
1093
1172
|
combined.set(chunk, offset);
|
|
1094
1173
|
offset += chunk.length;
|
|
1095
1174
|
}
|
|
1096
1175
|
} catch (err) {
|
|
1097
|
-
|
|
1176
|
+
_iterator5.e(err);
|
|
1098
1177
|
} finally {
|
|
1099
|
-
|
|
1178
|
+
_iterator5.f();
|
|
1100
1179
|
}
|
|
1101
1180
|
this.audioChunks = [];
|
|
1102
1181
|
var blob = new Blob([combined], {
|
|
@@ -1115,45 +1194,53 @@ window.chatInteractionManager = function () {
|
|
|
1115
1194
|
this.playAudioBlob(blob);
|
|
1116
1195
|
},
|
|
1117
1196
|
playAudioBlob: function playAudioBlob(blob) {
|
|
1118
|
-
var
|
|
1197
|
+
var _this1 = this;
|
|
1119
1198
|
var url = URL.createObjectURL(blob);
|
|
1120
1199
|
var audio = new Audio(url);
|
|
1121
1200
|
this.currentAudioUrl = url;
|
|
1122
1201
|
this.currentAudioElement = audio;
|
|
1123
1202
|
this.isPlayingAudio = true;
|
|
1124
1203
|
audio.addEventListener('ended', function () {
|
|
1125
|
-
|
|
1126
|
-
|
|
1204
|
+
_this1.currentAudioElement = null;
|
|
1205
|
+
_this1.currentAudioUrl = null;
|
|
1127
1206
|
URL.revokeObjectURL(url);
|
|
1128
|
-
|
|
1207
|
+
_this1.playNextInQueue();
|
|
1129
1208
|
});
|
|
1130
1209
|
audio.addEventListener('error', function () {
|
|
1131
|
-
|
|
1132
|
-
|
|
1210
|
+
_this1.currentAudioElement = null;
|
|
1211
|
+
_this1.currentAudioUrl = null;
|
|
1133
1212
|
URL.revokeObjectURL(url);
|
|
1134
|
-
|
|
1213
|
+
_this1.playNextInQueue();
|
|
1135
1214
|
});
|
|
1136
1215
|
audio.play()["catch"](function (err) {
|
|
1137
1216
|
console.error("Audio playback error:", err);
|
|
1138
|
-
|
|
1139
|
-
|
|
1217
|
+
_this1.currentAudioElement = null;
|
|
1218
|
+
_this1.currentAudioUrl = null;
|
|
1140
1219
|
URL.revokeObjectURL(url);
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1220
|
+
_this1.audioPlayQueue = [];
|
|
1221
|
+
_this1.isPlayingAudio = false;
|
|
1222
|
+
_this1.ttsPlayingMessageIndex = -1;
|
|
1223
|
+
_this1.$nextTick(function () {
|
|
1224
|
+
return _this1.updateTtsPlaybackButtons();
|
|
1225
|
+
});
|
|
1144
1226
|
});
|
|
1145
1227
|
},
|
|
1146
1228
|
playNextInQueue: function playNextInQueue() {
|
|
1229
|
+
var _this10 = this;
|
|
1147
1230
|
if (this.audioPlayQueue.length > 0) {
|
|
1148
1231
|
var nextBlob = this.audioPlayQueue.shift();
|
|
1149
1232
|
this.playAudioBlob(nextBlob);
|
|
1150
1233
|
} else {
|
|
1151
1234
|
this.isPlayingAudio = false;
|
|
1152
1235
|
this.ttsPlayingMessageIndex = -1;
|
|
1236
|
+
this.$nextTick(function () {
|
|
1237
|
+
return _this10.updateTtsPlaybackButtons();
|
|
1238
|
+
});
|
|
1153
1239
|
this.conversationModeOnAudioEnded();
|
|
1154
1240
|
}
|
|
1155
1241
|
},
|
|
1156
1242
|
stopAudio: function stopAudio() {
|
|
1243
|
+
var _this11 = this;
|
|
1157
1244
|
if (this.currentAudioElement) {
|
|
1158
1245
|
this.currentAudioElement.pause();
|
|
1159
1246
|
this.currentAudioElement.currentTime = 0;
|
|
@@ -1167,6 +1254,9 @@ window.chatInteractionManager = function () {
|
|
|
1167
1254
|
this.audioPlayQueue = [];
|
|
1168
1255
|
this.isPlayingAudio = false;
|
|
1169
1256
|
this.ttsPlayingMessageIndex = -1;
|
|
1257
|
+
this.$nextTick(function () {
|
|
1258
|
+
return _this11.updateTtsPlaybackButtons();
|
|
1259
|
+
});
|
|
1170
1260
|
},
|
|
1171
1261
|
toggleConversationMode: function toggleConversationMode() {
|
|
1172
1262
|
if (this.isConversationMode) {
|
|
@@ -1176,7 +1266,7 @@ window.chatInteractionManager = function () {
|
|
|
1176
1266
|
}
|
|
1177
1267
|
},
|
|
1178
1268
|
startConversationMode: function startConversationMode() {
|
|
1179
|
-
var
|
|
1269
|
+
var _this12 = this;
|
|
1180
1270
|
if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {
|
|
1181
1271
|
return;
|
|
1182
1272
|
}
|
|
@@ -1196,30 +1286,30 @@ window.chatInteractionManager = function () {
|
|
|
1196
1286
|
}
|
|
1197
1287
|
}).then(function (stream) {
|
|
1198
1288
|
var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus') ? 'audio/ogg;codecs=opus' : MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
|
|
1199
|
-
|
|
1289
|
+
_this12.mediaRecorder = new MediaRecorder(stream, {
|
|
1200
1290
|
mimeType: mimeType,
|
|
1201
1291
|
audioBitsPerSecond: 128000
|
|
1202
1292
|
});
|
|
1203
|
-
|
|
1204
|
-
|
|
1293
|
+
_this12._conversationSubject = new signalR.Subject();
|
|
1294
|
+
_this12._conversationStream = stream;
|
|
1205
1295
|
|
|
1206
1296
|
// Create an AnalyserNode for volume-based interrupt detection.
|
|
1207
1297
|
var AudioCtx = window.AudioContext || window.webkitAudioContext;
|
|
1208
1298
|
if (AudioCtx) {
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
var micSource =
|
|
1213
|
-
micSource.connect(
|
|
1299
|
+
_this12._conversationAudioCtx = new AudioCtx();
|
|
1300
|
+
_this12._conversationAnalyser = _this12._conversationAudioCtx.createAnalyser();
|
|
1301
|
+
_this12._conversationAnalyser.fftSize = 256;
|
|
1302
|
+
var micSource = _this12._conversationAudioCtx.createMediaStreamSource(stream);
|
|
1303
|
+
micSource.connect(_this12._conversationAnalyser);
|
|
1214
1304
|
}
|
|
1215
1305
|
var pendingChunk = Promise.resolve();
|
|
1216
|
-
var analyser =
|
|
1306
|
+
var analyser = _this12._conversationAnalyser;
|
|
1217
1307
|
var interruptVolumeThreshold = 30;
|
|
1218
|
-
|
|
1308
|
+
_this12.mediaRecorder.addEventListener('dataavailable', function (e) {
|
|
1219
1309
|
if (e.data && e.data.size > 0) {
|
|
1220
1310
|
// During TTS playback, check mic volume to detect
|
|
1221
1311
|
// user interruption (speaking above threshold).
|
|
1222
|
-
if (
|
|
1312
|
+
if (_this12.isPlayingAudio && analyser) {
|
|
1223
1313
|
var freqData = new Uint8Array(analyser.frequencyBinCount);
|
|
1224
1314
|
analyser.getByteFrequencyData(freqData);
|
|
1225
1315
|
var sum = 0;
|
|
@@ -1229,7 +1319,7 @@ window.chatInteractionManager = function () {
|
|
|
1229
1319
|
var avg = sum / freqData.length;
|
|
1230
1320
|
if (avg >= interruptVolumeThreshold) {
|
|
1231
1321
|
// User is speaking — interrupt TTS playback.
|
|
1232
|
-
|
|
1322
|
+
_this12.stopAudio();
|
|
1233
1323
|
}
|
|
1234
1324
|
}
|
|
1235
1325
|
|
|
@@ -1251,7 +1341,7 @@ window.chatInteractionManager = function () {
|
|
|
1251
1341
|
}, '');
|
|
1252
1342
|
base64 = btoa(binaryString);
|
|
1253
1343
|
try {
|
|
1254
|
-
|
|
1344
|
+
_this12._conversationSubject.next(base64);
|
|
1255
1345
|
} catch (err) {
|
|
1256
1346
|
// Subject may have been completed already.
|
|
1257
1347
|
}
|
|
@@ -1262,27 +1352,27 @@ window.chatInteractionManager = function () {
|
|
|
1262
1352
|
})));
|
|
1263
1353
|
}
|
|
1264
1354
|
});
|
|
1265
|
-
|
|
1355
|
+
_this12.mediaRecorder.addEventListener('stop', function () {
|
|
1266
1356
|
stream.getTracks().forEach(function (track) {
|
|
1267
1357
|
return track.stop();
|
|
1268
1358
|
});
|
|
1269
1359
|
pendingChunk.then(function () {
|
|
1270
1360
|
try {
|
|
1271
|
-
|
|
1361
|
+
_this12._conversationSubject.complete();
|
|
1272
1362
|
} catch (err) {
|
|
1273
1363
|
// Already completed.
|
|
1274
1364
|
}
|
|
1275
1365
|
});
|
|
1276
1366
|
});
|
|
1277
|
-
var itemId =
|
|
1367
|
+
var itemId = _this12.getItemId();
|
|
1278
1368
|
var language = navigator.language || document.documentElement.lang || 'en-US';
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1369
|
+
_this12.connection.send("StartConversation", itemId, _this12._conversationSubject, mimeType, language);
|
|
1370
|
+
_this12.mediaRecorder.start(250);
|
|
1371
|
+
_this12.isRecording = true;
|
|
1282
1372
|
})["catch"](function (err) {
|
|
1283
1373
|
console.error('Microphone access denied:', err);
|
|
1284
|
-
|
|
1285
|
-
|
|
1374
|
+
_this12.isConversationMode = false;
|
|
1375
|
+
_this12.updateConversationButton();
|
|
1286
1376
|
});
|
|
1287
1377
|
},
|
|
1288
1378
|
stopConversationMode: function stopConversationMode() {
|
|
@@ -1386,12 +1476,12 @@ window.chatInteractionManager = function () {
|
|
|
1386
1476
|
return removedCount;
|
|
1387
1477
|
},
|
|
1388
1478
|
scrollToBottom: function scrollToBottom() {
|
|
1389
|
-
var
|
|
1479
|
+
var _this13 = this;
|
|
1390
1480
|
if (!this.autoScroll) {
|
|
1391
1481
|
return;
|
|
1392
1482
|
}
|
|
1393
1483
|
setTimeout(function () {
|
|
1394
|
-
|
|
1484
|
+
_this13.chatContainer.scrollTop = _this13.chatContainer.scrollHeight - _this13.chatContainer.clientHeight;
|
|
1395
1485
|
}, 50);
|
|
1396
1486
|
},
|
|
1397
1487
|
handleUserInput: function handleUserInput(event) {
|
|
@@ -1407,7 +1497,7 @@ window.chatInteractionManager = function () {
|
|
|
1407
1497
|
return document.querySelector('[data-chat-interaction-save-indicator]');
|
|
1408
1498
|
},
|
|
1409
1499
|
showSaveIndicator: function showSaveIndicator(text, className) {
|
|
1410
|
-
var
|
|
1500
|
+
var _this14 = this;
|
|
1411
1501
|
var indicator = this.getSaveIndicatorElement();
|
|
1412
1502
|
if (!indicator) {
|
|
1413
1503
|
return;
|
|
@@ -1423,7 +1513,7 @@ window.chatInteractionManager = function () {
|
|
|
1423
1513
|
}
|
|
1424
1514
|
this.saveIndicatorTimeout = setTimeout(function () {
|
|
1425
1515
|
indicator.textContent = '';
|
|
1426
|
-
|
|
1516
|
+
_this14.saveIndicatorTimeout = null;
|
|
1427
1517
|
}, 3000);
|
|
1428
1518
|
},
|
|
1429
1519
|
clearPendingSettingsSave: function clearPendingSettingsSave() {
|
|
@@ -1497,10 +1587,10 @@ window.chatInteractionManager = function () {
|
|
|
1497
1587
|
return false;
|
|
1498
1588
|
},
|
|
1499
1589
|
validateSettings: function validateSettings() {
|
|
1500
|
-
var
|
|
1590
|
+
var _this15 = this;
|
|
1501
1591
|
var isValid = true;
|
|
1502
1592
|
this.getSettingInputs().forEach(function (input) {
|
|
1503
|
-
isValid =
|
|
1593
|
+
isValid = _this15.validateSettingInput(input) && isValid;
|
|
1504
1594
|
});
|
|
1505
1595
|
return isValid;
|
|
1506
1596
|
},
|
|
@@ -1523,7 +1613,7 @@ window.chatInteractionManager = function () {
|
|
|
1523
1613
|
return document.querySelectorAll('input[name^="ChatInteraction."]:not([name*=".Tools["]):not([name*=".Connections["]), ' + 'select[name^="ChatInteraction."]:not([name*=".Tools["]):not([name*=".Connections["]), ' + 'textarea[name^="ChatInteraction."]:not([name*=".Tools["]):not([name*=".Connections["])');
|
|
1524
1614
|
},
|
|
1525
1615
|
getSelectedGroupValues: function getSelectedGroupValues(groupName, fallbackSelector) {
|
|
1526
|
-
var explicitSelections = document.querySelectorAll(".capability-checkbox[data-save-group=\"".concat(groupName, "\"]:checked"));
|
|
1616
|
+
var explicitSelections = document.querySelectorAll(".capability-checkbox[data-save-group=\"".concat(groupName, "\"]:checked, .capability-checkbox[data-group=\"").concat(groupName, "\"]:checked"));
|
|
1527
1617
|
if (explicitSelections.length > 0) {
|
|
1528
1618
|
var _values = [];
|
|
1529
1619
|
explicitSelections.forEach(function (checkbox) {
|
|
@@ -1596,12 +1686,12 @@ window.chatInteractionManager = function () {
|
|
|
1596
1686
|
}
|
|
1597
1687
|
},
|
|
1598
1688
|
scheduleNotificationDismiss: function scheduleNotificationDismiss(notification) {
|
|
1599
|
-
var
|
|
1689
|
+
var _this16 = this;
|
|
1600
1690
|
if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {
|
|
1601
1691
|
return;
|
|
1602
1692
|
}
|
|
1603
1693
|
this.notificationDismissTimers[notification.type] = setTimeout(function () {
|
|
1604
|
-
|
|
1694
|
+
_this16.removeNotification(notification.type);
|
|
1605
1695
|
}, notification.autoDismissMs);
|
|
1606
1696
|
},
|
|
1607
1697
|
clearNotificationDismiss: function clearNotificationDismiss(notificationType) {
|
|
@@ -1641,7 +1731,7 @@ window.chatInteractionManager = function () {
|
|
|
1641
1731
|
this.showPlaceholder();
|
|
1642
1732
|
},
|
|
1643
1733
|
initializeApp: function initializeApp() {
|
|
1644
|
-
var
|
|
1734
|
+
var _this17 = this;
|
|
1645
1735
|
this.inputElement = document.querySelector(config.inputElementSelector);
|
|
1646
1736
|
this.buttonElement = document.querySelector(config.sendButtonElementSelector);
|
|
1647
1737
|
this.chatContainer = document.querySelector(config.chatContainerElementSelector);
|
|
@@ -1653,59 +1743,59 @@ window.chatInteractionManager = function () {
|
|
|
1653
1743
|
|
|
1654
1744
|
// Pause auto-scroll when the user manually scrolls up during streaming.
|
|
1655
1745
|
this.chatContainer.addEventListener('scroll', function () {
|
|
1656
|
-
if (!
|
|
1746
|
+
if (!_this17.stream) {
|
|
1657
1747
|
return;
|
|
1658
1748
|
}
|
|
1659
1749
|
var threshold = 30;
|
|
1660
|
-
var atBottom =
|
|
1661
|
-
|
|
1750
|
+
var atBottom = _this17.chatContainer.scrollHeight - _this17.chatContainer.clientHeight - _this17.chatContainer.scrollTop <= threshold;
|
|
1751
|
+
_this17.autoScroll = atBottom;
|
|
1662
1752
|
});
|
|
1663
1753
|
this.inputElement.addEventListener('keyup', function (event) {
|
|
1664
|
-
if (
|
|
1754
|
+
if (_this17.stream != null) {
|
|
1665
1755
|
return;
|
|
1666
1756
|
}
|
|
1667
1757
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
1668
|
-
|
|
1758
|
+
_this17.buttonElement.click();
|
|
1669
1759
|
}
|
|
1670
1760
|
});
|
|
1671
1761
|
this.inputElement.addEventListener('input', function (e) {
|
|
1672
|
-
|
|
1762
|
+
_this17.handleUserInput(e);
|
|
1673
1763
|
if (e.target.value.trim()) {
|
|
1674
|
-
|
|
1764
|
+
_this17.buttonElement.removeAttribute('disabled');
|
|
1675
1765
|
} else {
|
|
1676
|
-
|
|
1766
|
+
_this17.buttonElement.setAttribute('disabled', true);
|
|
1677
1767
|
}
|
|
1678
1768
|
});
|
|
1679
1769
|
this.inputElement.addEventListener('paste', function (e) {
|
|
1680
1770
|
// Use setTimeout to allow the paste to complete before checking the value
|
|
1681
1771
|
setTimeout(function () {
|
|
1682
|
-
|
|
1683
|
-
if (
|
|
1684
|
-
|
|
1772
|
+
_this17.prompt = _this17.inputElement.value;
|
|
1773
|
+
if (_this17.inputElement.value.trim()) {
|
|
1774
|
+
_this17.buttonElement.removeAttribute('disabled');
|
|
1685
1775
|
} else {
|
|
1686
|
-
|
|
1776
|
+
_this17.buttonElement.setAttribute('disabled', true);
|
|
1687
1777
|
}
|
|
1688
1778
|
}, 0);
|
|
1689
1779
|
});
|
|
1690
1780
|
this.buttonElement.addEventListener('click', function () {
|
|
1691
|
-
if (
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1781
|
+
if (_this17.stream != null) {
|
|
1782
|
+
_this17.stream.dispose();
|
|
1783
|
+
_this17.stream = null;
|
|
1784
|
+
_this17.streamingFinished();
|
|
1785
|
+
_this17.hideTypingIndicator();
|
|
1696
1786
|
|
|
1697
1787
|
// Clean up: remove empty assistant message or stop streaming animation.
|
|
1698
|
-
if (
|
|
1699
|
-
var lastMsg =
|
|
1788
|
+
if (_this17.messages.length > 0) {
|
|
1789
|
+
var lastMsg = _this17.messages[_this17.messages.length - 1];
|
|
1700
1790
|
if (lastMsg.role === 'assistant' && !lastMsg.content) {
|
|
1701
|
-
|
|
1791
|
+
_this17.messages.pop();
|
|
1702
1792
|
} else if (lastMsg.isStreaming) {
|
|
1703
1793
|
lastMsg.isStreaming = false;
|
|
1704
1794
|
}
|
|
1705
1795
|
}
|
|
1706
1796
|
return;
|
|
1707
1797
|
}
|
|
1708
|
-
|
|
1798
|
+
_this17.sendMessage();
|
|
1709
1799
|
});
|
|
1710
1800
|
var chatInteractionItems = document.getElementsByClassName('chat-interaction-history-item');
|
|
1711
1801
|
for (var i = 0; i < chatInteractionItems.length; i++) {
|
|
@@ -1716,11 +1806,11 @@ window.chatInteractionManager = function () {
|
|
|
1716
1806
|
console.error('An element with the class chat-interaction-history-item with no data-interaction-id set.');
|
|
1717
1807
|
return;
|
|
1718
1808
|
}
|
|
1719
|
-
|
|
1809
|
+
_this17.loadInteraction(itemId);
|
|
1720
1810
|
});
|
|
1721
1811
|
}
|
|
1722
|
-
for (var
|
|
1723
|
-
this.addMessage(config.messages[
|
|
1812
|
+
for (var _i4 = 0; _i4 < config.messages.length; _i4++) {
|
|
1813
|
+
this.addMessage(config.messages[_i4]);
|
|
1724
1814
|
}
|
|
1725
1815
|
|
|
1726
1816
|
// Delegate click for code block copy buttons.
|
|
@@ -1747,20 +1837,20 @@ window.chatInteractionManager = function () {
|
|
|
1747
1837
|
}
|
|
1748
1838
|
document.addEventListener('input', function (event) {
|
|
1749
1839
|
if (event.target.matches('.setting-input[data-setting]')) {
|
|
1750
|
-
|
|
1751
|
-
|
|
1840
|
+
_this17.validateSettingInput(event.target);
|
|
1841
|
+
_this17.queueSettingsSave();
|
|
1752
1842
|
}
|
|
1753
1843
|
});
|
|
1754
1844
|
document.addEventListener('change', function (event) {
|
|
1755
|
-
if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .group-toggle, .ci-agent-global-toggle')) {
|
|
1845
|
+
if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {
|
|
1756
1846
|
if (event.target.matches('.setting-input[data-setting]')) {
|
|
1757
|
-
|
|
1847
|
+
_this17.validateSettingInput(event.target);
|
|
1758
1848
|
}
|
|
1759
|
-
|
|
1849
|
+
_this17.queueSettingsSave();
|
|
1760
1850
|
return;
|
|
1761
1851
|
}
|
|
1762
1852
|
if (event.target.closest('.prompt-template-parameters-input, .prompt-template-id-input')) {
|
|
1763
|
-
|
|
1853
|
+
_this17.queueSettingsSave();
|
|
1764
1854
|
}
|
|
1765
1855
|
});
|
|
1766
1856
|
document.addEventListener('click', function (event) {
|
|
@@ -1768,7 +1858,7 @@ window.chatInteractionManager = function () {
|
|
|
1768
1858
|
return;
|
|
1769
1859
|
}
|
|
1770
1860
|
setTimeout(function () {
|
|
1771
|
-
|
|
1861
|
+
_this17.queueSettingsSave();
|
|
1772
1862
|
}, 0);
|
|
1773
1863
|
});
|
|
1774
1864
|
|
|
@@ -1778,7 +1868,7 @@ window.chatInteractionManager = function () {
|
|
|
1778
1868
|
clearHistoryBtn.addEventListener('click', function () {
|
|
1779
1869
|
var itemId = clearHistoryBtn.getAttribute('data-interaction-id');
|
|
1780
1870
|
if (itemId) {
|
|
1781
|
-
|
|
1871
|
+
_this17.clearHistory(itemId);
|
|
1782
1872
|
}
|
|
1783
1873
|
});
|
|
1784
1874
|
}
|
|
@@ -1789,7 +1879,7 @@ window.chatInteractionManager = function () {
|
|
|
1789
1879
|
if (this.micButton) {
|
|
1790
1880
|
this.micButton.style.display = '';
|
|
1791
1881
|
this.micButton.addEventListener('click', function () {
|
|
1792
|
-
|
|
1882
|
+
_this17.toggleRecording();
|
|
1793
1883
|
});
|
|
1794
1884
|
}
|
|
1795
1885
|
}
|
|
@@ -1799,7 +1889,7 @@ window.chatInteractionManager = function () {
|
|
|
1799
1889
|
this.conversationButton = document.querySelector(config.conversationButtonElementSelector);
|
|
1800
1890
|
if (this.conversationButton) {
|
|
1801
1891
|
this.conversationButton.addEventListener('click', function () {
|
|
1802
|
-
|
|
1892
|
+
_this17.toggleConversationMode();
|
|
1803
1893
|
});
|
|
1804
1894
|
}
|
|
1805
1895
|
}
|
|
@@ -1817,29 +1907,38 @@ window.chatInteractionManager = function () {
|
|
|
1817
1907
|
},
|
|
1818
1908
|
clearHistory: function clearHistory(itemId) {
|
|
1819
1909
|
var self = this;
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1910
|
+
var clearHistoryConfirmed = function clearHistoryConfirmed() {
|
|
1911
|
+
// Cancel any active stream before clearing history.
|
|
1912
|
+
if (self.stream) {
|
|
1913
|
+
self.stream.dispose();
|
|
1914
|
+
self.stream = null;
|
|
1915
|
+
self.hideTypingIndicator();
|
|
1916
|
+
self.streamingFinished();
|
|
1917
|
+
}
|
|
1918
|
+
self.connection.invoke("ClearHistory", itemId)["catch"](function (err) {
|
|
1919
|
+
return console.error('Error clearing history:', err);
|
|
1920
|
+
});
|
|
1921
|
+
};
|
|
1922
|
+
if (typeof confirmDialog === 'function') {
|
|
1923
|
+
confirmDialog({
|
|
1924
|
+
title: config.clearHistoryTitle,
|
|
1925
|
+
message: config.clearHistoryMessage,
|
|
1926
|
+
okText: config.clearHistoryOkText,
|
|
1927
|
+
cancelText: config.clearHistoryCancelText,
|
|
1928
|
+
callback: function callback(confirmed) {
|
|
1929
|
+
if (confirmed) {
|
|
1930
|
+
clearHistoryConfirmed();
|
|
1833
1931
|
}
|
|
1834
|
-
self.connection.invoke("ClearHistory", itemId)["catch"](function (err) {
|
|
1835
|
-
return console.error('Error clearing history:', err);
|
|
1836
|
-
});
|
|
1837
1932
|
}
|
|
1838
|
-
}
|
|
1839
|
-
|
|
1933
|
+
});
|
|
1934
|
+
return;
|
|
1935
|
+
}
|
|
1936
|
+
if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {
|
|
1937
|
+
clearHistoryConfirmed();
|
|
1938
|
+
}
|
|
1840
1939
|
},
|
|
1841
1940
|
debouncedSaveSettings: function debouncedSaveSettings() {
|
|
1842
|
-
var
|
|
1941
|
+
var _this18 = this;
|
|
1843
1942
|
// Clear any existing timeout to reset the debounce timer
|
|
1844
1943
|
this.clearPendingSettingsSave();
|
|
1845
1944
|
|
|
@@ -1850,11 +1949,11 @@ window.chatInteractionManager = function () {
|
|
|
1850
1949
|
|
|
1851
1950
|
// Set a new timeout to save after 850ms of no changes
|
|
1852
1951
|
this.saveSettingsTimeout = setTimeout(function () {
|
|
1853
|
-
if (
|
|
1854
|
-
|
|
1855
|
-
|
|
1952
|
+
if (_this18.settingsDirty) {
|
|
1953
|
+
_this18.saveSettings();
|
|
1954
|
+
_this18.settingsDirty = false;
|
|
1856
1955
|
}
|
|
1857
|
-
|
|
1956
|
+
_this18.saveSettingsTimeout = null;
|
|
1858
1957
|
}, 850);
|
|
1859
1958
|
},
|
|
1860
1959
|
getSelectedToolNames: function getSelectedToolNames() {
|
|
@@ -1870,7 +1969,7 @@ window.chatInteractionManager = function () {
|
|
|
1870
1969
|
return this.getSelectedGroupValues('agentNames', 'input[type="checkbox"][name$="].IsSelected"][name^="ChatInteraction.Agents["]:checked');
|
|
1871
1970
|
},
|
|
1872
1971
|
saveSettings: function saveSettings() {
|
|
1873
|
-
var
|
|
1972
|
+
var _this19 = this;
|
|
1874
1973
|
var itemId = this.getItemId();
|
|
1875
1974
|
if (!itemId) {
|
|
1876
1975
|
return Promise.resolve();
|
|
@@ -1915,7 +2014,7 @@ window.chatInteractionManager = function () {
|
|
|
1915
2014
|
}
|
|
1916
2015
|
return this.connection.invoke("SaveSettings", itemId, settings)["catch"](function (err) {
|
|
1917
2016
|
console.error('Error saving settings:', err);
|
|
1918
|
-
|
|
2017
|
+
_this19.showSaveIndicator('Save failed', 'text-danger');
|
|
1919
2018
|
});
|
|
1920
2019
|
},
|
|
1921
2020
|
flushPendingSave: function flushPendingSave() {
|
|
@@ -1942,10 +2041,12 @@ window.chatInteractionManager = function () {
|
|
|
1942
2041
|
this.isInteractionStarted = true;
|
|
1943
2042
|
},
|
|
1944
2043
|
copyResponse: function copyResponse(message) {
|
|
1945
|
-
|
|
2044
|
+
var _ref13, _message$copyContent;
|
|
2045
|
+
var text = message && _typeof(message) === 'object' ? (_ref13 = (_message$copyContent = message.copyContent) !== null && _message$copyContent !== void 0 ? _message$copyContent : message.content) !== null && _ref13 !== void 0 ? _ref13 : '' : message !== null && message !== void 0 ? message : '';
|
|
2046
|
+
navigator.clipboard.writeText(text);
|
|
1946
2047
|
},
|
|
1947
2048
|
startRecording: function startRecording() {
|
|
1948
|
-
var
|
|
2049
|
+
var _this20 = this;
|
|
1949
2050
|
if (this.isRecording || !this.connection) {
|
|
1950
2051
|
return;
|
|
1951
2052
|
}
|
|
@@ -1957,16 +2058,16 @@ window.chatInteractionManager = function () {
|
|
|
1957
2058
|
}
|
|
1958
2059
|
}).then(function (stream) {
|
|
1959
2060
|
var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus') ? 'audio/ogg;codecs=opus' : MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
|
|
1960
|
-
|
|
2061
|
+
_this20.mediaRecorder = new MediaRecorder(stream, {
|
|
1961
2062
|
mimeType: mimeType,
|
|
1962
2063
|
audioBitsPerSecond: 128000
|
|
1963
2064
|
});
|
|
1964
|
-
|
|
1965
|
-
|
|
2065
|
+
_this20.preRecordingPrompt = _this20.prompt;
|
|
2066
|
+
_this20._audioInputSent = false;
|
|
1966
2067
|
var subject = new signalR.Subject();
|
|
1967
|
-
var itemId =
|
|
2068
|
+
var itemId = _this20.getItemId();
|
|
1968
2069
|
var pendingChunk = Promise.resolve();
|
|
1969
|
-
|
|
2070
|
+
_this20.mediaRecorder.addEventListener('dataavailable', function (e) {
|
|
1970
2071
|
if (e.data && e.data.size > 0) {
|
|
1971
2072
|
pendingChunk = pendingChunk.then(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
1972
2073
|
var data, uint8Array, binaryString, base64;
|
|
@@ -1990,7 +2091,7 @@ window.chatInteractionManager = function () {
|
|
|
1990
2091
|
})));
|
|
1991
2092
|
}
|
|
1992
2093
|
});
|
|
1993
|
-
|
|
2094
|
+
_this20.mediaRecorder.addEventListener('stop', function () {
|
|
1994
2095
|
stream.getTracks().forEach(function (track) {
|
|
1995
2096
|
return track.stop();
|
|
1996
2097
|
});
|
|
@@ -1999,10 +2100,10 @@ window.chatInteractionManager = function () {
|
|
|
1999
2100
|
});
|
|
2000
2101
|
});
|
|
2001
2102
|
var language = navigator.language || document.documentElement.lang || 'en-US';
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2103
|
+
_this20.connection.send("SendAudioStream", itemId, subject, mimeType, language);
|
|
2104
|
+
_this20.mediaRecorder.start(250);
|
|
2105
|
+
_this20.isRecording = true;
|
|
2106
|
+
_this20.updateMicButton();
|
|
2006
2107
|
})["catch"](function (err) {
|
|
2007
2108
|
console.error('Microphone access denied:', err);
|
|
2008
2109
|
});
|
|
@@ -2056,15 +2157,19 @@ window.chatInteractionManager = function () {
|
|
|
2056
2157
|
}
|
|
2057
2158
|
},
|
|
2058
2159
|
mounted: function mounted() {
|
|
2059
|
-
var
|
|
2160
|
+
var _this21 = this;
|
|
2060
2161
|
_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
|
|
2061
2162
|
return _regenerator().w(function (_context5) {
|
|
2062
2163
|
while (1) switch (_context5.n) {
|
|
2063
2164
|
case 0:
|
|
2064
2165
|
_context5.n = 1;
|
|
2065
|
-
return
|
|
2166
|
+
return _this21.startConnection();
|
|
2066
2167
|
case 1:
|
|
2067
|
-
|
|
2168
|
+
_this21.initializeApp();
|
|
2169
|
+
_this21.$nextTick(function () {
|
|
2170
|
+
refreshFontAwesomeIcons(_this21.$el);
|
|
2171
|
+
_this21.fontAwesomeObserver = observeFontAwesomeIcons(_this21.$el);
|
|
2172
|
+
});
|
|
2068
2173
|
case 2:
|
|
2069
2174
|
return _context5.a(2);
|
|
2070
2175
|
}
|
|
@@ -2076,6 +2181,10 @@ window.chatInteractionManager = function () {
|
|
|
2076
2181
|
beforeUnmount: function beforeUnmount() {
|
|
2077
2182
|
window.removeEventListener('beforeunload', this.handleBeforeUnload);
|
|
2078
2183
|
window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);
|
|
2184
|
+
if (this.fontAwesomeObserver) {
|
|
2185
|
+
this.fontAwesomeObserver.disconnect();
|
|
2186
|
+
this.fontAwesomeObserver = null;
|
|
2187
|
+
}
|
|
2079
2188
|
this.stopAudio(false);
|
|
2080
2189
|
if (this.stream) {
|
|
2081
2190
|
this.stream.dispose();
|
|
@@ -2093,6 +2202,535 @@ window.chatInteractionManager = function () {
|
|
|
2093
2202
|
initialize: initialize
|
|
2094
2203
|
};
|
|
2095
2204
|
}();
|
|
2205
|
+
window.chatInteractionDocumentManager = function () {
|
|
2206
|
+
var managerStateKey = '__chatInteractionDocumentManagerState';
|
|
2207
|
+
function normalizeDocumentInfo(document) {
|
|
2208
|
+
if (!document || _typeof(document) !== 'object') {
|
|
2209
|
+
return null;
|
|
2210
|
+
}
|
|
2211
|
+
return {
|
|
2212
|
+
documentId: document.documentId || document.DocumentId || '',
|
|
2213
|
+
fileName: document.fileName || document.FileName || '',
|
|
2214
|
+
fileSize: document.fileSize || document.FileSize || 0
|
|
2215
|
+
};
|
|
2216
|
+
}
|
|
2217
|
+
function formatFileSize(bytes) {
|
|
2218
|
+
if (!bytes || bytes < 1024) {
|
|
2219
|
+
return (bytes || 0) + ' B';
|
|
2220
|
+
}
|
|
2221
|
+
if (bytes < 1024 * 1024) {
|
|
2222
|
+
return (bytes / 1024).toFixed(1) + ' KB';
|
|
2223
|
+
}
|
|
2224
|
+
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
2225
|
+
}
|
|
2226
|
+
function getDocumentKey(fileName, fileSize) {
|
|
2227
|
+
return (fileName || '').trim().toLowerCase() + '::' + (fileSize || 0);
|
|
2228
|
+
}
|
|
2229
|
+
function isDuplicateFile(file, knownKeys) {
|
|
2230
|
+
return knownKeys.has(getDocumentKey(file.name, file.size));
|
|
2231
|
+
}
|
|
2232
|
+
function getDocumentsFromDom(container) {
|
|
2233
|
+
if (!container) {
|
|
2234
|
+
return [];
|
|
2235
|
+
}
|
|
2236
|
+
return Array.from(container.querySelectorAll('[data-chat-document-id]')).map(function (element) {
|
|
2237
|
+
return normalizeDocumentInfo({
|
|
2238
|
+
documentId: element.dataset.chatDocumentId,
|
|
2239
|
+
fileName: element.dataset.chatDocumentName,
|
|
2240
|
+
fileSize: Number(element.dataset.chatDocumentSize || 0)
|
|
2241
|
+
});
|
|
2242
|
+
}).filter(function (document) {
|
|
2243
|
+
return document && document.documentId;
|
|
2244
|
+
});
|
|
2245
|
+
}
|
|
2246
|
+
function initialize(config) {
|
|
2247
|
+
if (!config || !config.itemId) {
|
|
2248
|
+
return;
|
|
2249
|
+
}
|
|
2250
|
+
var fileInput = document.getElementById('chat-doc-upload');
|
|
2251
|
+
var documentsList = document.getElementById('chat-documents-list');
|
|
2252
|
+
var status = document.getElementById('chat-doc-upload-status');
|
|
2253
|
+
var progressContainer = document.getElementById('chat-doc-upload-progress');
|
|
2254
|
+
var progressBar = document.getElementById('chat-doc-upload-progress-bar');
|
|
2255
|
+
var uploadQueue = document.getElementById('chat-doc-upload-queue');
|
|
2256
|
+
if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {
|
|
2257
|
+
return;
|
|
2258
|
+
}
|
|
2259
|
+
var previousState = fileInput[managerStateKey];
|
|
2260
|
+
if (previousState && typeof previousState.dispose === 'function') {
|
|
2261
|
+
previousState.dispose();
|
|
2262
|
+
}
|
|
2263
|
+
var interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : []).map(normalizeDocumentInfo).filter(function (document) {
|
|
2264
|
+
return document && document.documentId;
|
|
2265
|
+
});
|
|
2266
|
+
if (interactionDocuments.length === 0) {
|
|
2267
|
+
interactionDocuments = getDocumentsFromDom(documentsList);
|
|
2268
|
+
}
|
|
2269
|
+
var uploadItems = [];
|
|
2270
|
+
var isUploadingDocuments = false;
|
|
2271
|
+
function createTextElement(tagName, className, text) {
|
|
2272
|
+
var element = document.createElement(tagName);
|
|
2273
|
+
if (className) {
|
|
2274
|
+
element.className = className;
|
|
2275
|
+
}
|
|
2276
|
+
element.textContent = text;
|
|
2277
|
+
return element;
|
|
2278
|
+
}
|
|
2279
|
+
function renderDocuments() {
|
|
2280
|
+
documentsList.innerHTML = '';
|
|
2281
|
+
if (interactionDocuments.length === 0) {
|
|
2282
|
+
documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));
|
|
2283
|
+
return;
|
|
2284
|
+
}
|
|
2285
|
+
interactionDocuments.forEach(function (documentInfo) {
|
|
2286
|
+
var row = window.document.createElement('div');
|
|
2287
|
+
row.className = 'd-flex justify-content-between align-items-start gap-2 border rounded px-2 py-2 bg-white chat-document-row';
|
|
2288
|
+
row.dataset.chatDocumentId = documentInfo.documentId;
|
|
2289
|
+
row.dataset.chatDocumentName = documentInfo.fileName;
|
|
2290
|
+
row.dataset.chatDocumentSize = documentInfo.fileSize;
|
|
2291
|
+
var details = window.document.createElement('div');
|
|
2292
|
+
details.className = 'me-2 min-w-0';
|
|
2293
|
+
var name = createTextElement('div', 'fw-semibold small', documentInfo.fileName || 'Document');
|
|
2294
|
+
var icon = window.document.createElement('i');
|
|
2295
|
+
icon.className = 'bi bi-file-earmark-text me-1';
|
|
2296
|
+
name.prepend(icon);
|
|
2297
|
+
var size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));
|
|
2298
|
+
details.appendChild(name);
|
|
2299
|
+
details.appendChild(size);
|
|
2300
|
+
var removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', ' Remove');
|
|
2301
|
+
removeButton.type = 'button';
|
|
2302
|
+
removeButton.dataset.documentId = documentInfo.documentId;
|
|
2303
|
+
var removeIcon = window.document.createElement('i');
|
|
2304
|
+
removeIcon.className = 'bi bi-trash';
|
|
2305
|
+
removeButton.prepend(removeIcon);
|
|
2306
|
+
removeButton.addEventListener('click', function () {
|
|
2307
|
+
return removeDocument(documentInfo.documentId);
|
|
2308
|
+
});
|
|
2309
|
+
row.appendChild(details);
|
|
2310
|
+
row.appendChild(removeButton);
|
|
2311
|
+
documentsList.appendChild(row);
|
|
2312
|
+
});
|
|
2313
|
+
}
|
|
2314
|
+
function showUploadStatus(message, cssClass) {
|
|
2315
|
+
if (!message) {
|
|
2316
|
+
status.textContent = '';
|
|
2317
|
+
status.className = 'small mt-2 d-none';
|
|
2318
|
+
return;
|
|
2319
|
+
}
|
|
2320
|
+
status.textContent = message;
|
|
2321
|
+
status.className = 'small mt-2 ' + (cssClass || 'text-muted');
|
|
2322
|
+
}
|
|
2323
|
+
function showUploadProgress(progress, message, cssClass) {
|
|
2324
|
+
if (progress === null || progress === undefined) {
|
|
2325
|
+
progressContainer.className = 'progress mt-2 d-none';
|
|
2326
|
+
progressContainer.setAttribute('aria-valuenow', '0');
|
|
2327
|
+
progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';
|
|
2328
|
+
progressBar.style.width = '0%';
|
|
2329
|
+
progressBar.textContent = '0%';
|
|
2330
|
+
return;
|
|
2331
|
+
}
|
|
2332
|
+
var roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));
|
|
2333
|
+
progressContainer.className = 'progress mt-2';
|
|
2334
|
+
progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());
|
|
2335
|
+
progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');
|
|
2336
|
+
progressBar.style.width = roundedProgress + '%';
|
|
2337
|
+
progressBar.textContent = message || roundedProgress + '%';
|
|
2338
|
+
}
|
|
2339
|
+
function getUploadStatePresentation(state) {
|
|
2340
|
+
switch (state) {
|
|
2341
|
+
case 'uploaded':
|
|
2342
|
+
return {
|
|
2343
|
+
label: 'Uploaded',
|
|
2344
|
+
badgeClass: 'text-bg-success',
|
|
2345
|
+
progressClass: 'bg-success'
|
|
2346
|
+
};
|
|
2347
|
+
case 'failed':
|
|
2348
|
+
return {
|
|
2349
|
+
label: 'Failed',
|
|
2350
|
+
badgeClass: 'text-bg-danger',
|
|
2351
|
+
progressClass: 'bg-danger'
|
|
2352
|
+
};
|
|
2353
|
+
case 'uploading':
|
|
2354
|
+
return {
|
|
2355
|
+
label: 'Uploading',
|
|
2356
|
+
badgeClass: 'text-bg-warning',
|
|
2357
|
+
progressClass: 'bg-warning progress-bar-striped progress-bar-animated'
|
|
2358
|
+
};
|
|
2359
|
+
default:
|
|
2360
|
+
return {
|
|
2361
|
+
label: 'Queued',
|
|
2362
|
+
badgeClass: 'text-bg-secondary',
|
|
2363
|
+
progressClass: 'bg-secondary progress-bar-striped progress-bar-animated'
|
|
2364
|
+
};
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
function formatUploadMessage(item) {
|
|
2368
|
+
if (item.status === 'failed' && item.error) {
|
|
2369
|
+
return item.error;
|
|
2370
|
+
}
|
|
2371
|
+
if (item.status === 'uploaded') {
|
|
2372
|
+
return 'Upload completed successfully.';
|
|
2373
|
+
}
|
|
2374
|
+
if (item.status === 'uploading') {
|
|
2375
|
+
return item.progress + '% uploaded';
|
|
2376
|
+
}
|
|
2377
|
+
return 'Waiting to upload...';
|
|
2378
|
+
}
|
|
2379
|
+
function renderUploadQueue() {
|
|
2380
|
+
uploadQueue.innerHTML = '';
|
|
2381
|
+
uploadItems.forEach(function (item) {
|
|
2382
|
+
var presentation = getUploadStatePresentation(item.status);
|
|
2383
|
+
var card = document.createElement('div');
|
|
2384
|
+
card.className = 'border rounded px-2 py-2 bg-white';
|
|
2385
|
+
var header = document.createElement('div');
|
|
2386
|
+
header.className = 'd-flex justify-content-between align-items-start gap-2';
|
|
2387
|
+
var fileDetails = document.createElement('div');
|
|
2388
|
+
fileDetails.className = 'flex-grow-1 min-w-0';
|
|
2389
|
+
fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));
|
|
2390
|
+
fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));
|
|
2391
|
+
var badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);
|
|
2392
|
+
header.appendChild(fileDetails);
|
|
2393
|
+
header.appendChild(badge);
|
|
2394
|
+
var progress = document.createElement('div');
|
|
2395
|
+
progress.className = 'progress mt-2';
|
|
2396
|
+
progress.setAttribute('role', 'progressbar');
|
|
2397
|
+
progress.setAttribute('aria-valuemin', '0');
|
|
2398
|
+
progress.setAttribute('aria-valuemax', '100');
|
|
2399
|
+
progress.setAttribute('aria-valuenow', item.progress.toString());
|
|
2400
|
+
var progressState = document.createElement('div');
|
|
2401
|
+
progressState.className = 'progress-bar ' + presentation.progressClass;
|
|
2402
|
+
progressState.style.width = item.progress + '%';
|
|
2403
|
+
progressState.textContent = item.progress + '%';
|
|
2404
|
+
progress.appendChild(progressState);
|
|
2405
|
+
var message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));
|
|
2406
|
+
card.appendChild(header);
|
|
2407
|
+
card.appendChild(progress);
|
|
2408
|
+
card.appendChild(message);
|
|
2409
|
+
uploadQueue.appendChild(card);
|
|
2410
|
+
});
|
|
2411
|
+
}
|
|
2412
|
+
function createUploadItem(file, index) {
|
|
2413
|
+
return {
|
|
2414
|
+
id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),
|
|
2415
|
+
fileName: file.name,
|
|
2416
|
+
fileSize: file.size,
|
|
2417
|
+
status: 'queued',
|
|
2418
|
+
progress: 0,
|
|
2419
|
+
error: null
|
|
2420
|
+
};
|
|
2421
|
+
}
|
|
2422
|
+
function updateUploadItem(itemId, updates) {
|
|
2423
|
+
uploadItems = uploadItems.map(function (item) {
|
|
2424
|
+
return item.id === itemId ? Object.assign({}, item, updates) : item;
|
|
2425
|
+
});
|
|
2426
|
+
renderUploadQueue();
|
|
2427
|
+
}
|
|
2428
|
+
function removeUploadItems(predicate) {
|
|
2429
|
+
uploadItems = uploadItems.filter(function (item) {
|
|
2430
|
+
return !predicate(item);
|
|
2431
|
+
});
|
|
2432
|
+
renderUploadQueue();
|
|
2433
|
+
}
|
|
2434
|
+
function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {
|
|
2435
|
+
return new Promise(function (resolve, reject) {
|
|
2436
|
+
var formData = new FormData();
|
|
2437
|
+
formData.append('chatInteractionId', config.itemId);
|
|
2438
|
+
formData.append('files', file);
|
|
2439
|
+
var xhr = new XMLHttpRequest();
|
|
2440
|
+
xhr.open('POST', config.uploadDocumentUrl, true);
|
|
2441
|
+
xhr.upload.addEventListener('progress', function (event) {
|
|
2442
|
+
if (!event.lengthComputable) {
|
|
2443
|
+
return;
|
|
2444
|
+
}
|
|
2445
|
+
var fileProgress = Math.round(event.loaded / event.total * 100);
|
|
2446
|
+
updateUploadItem(itemIdToUpdate, {
|
|
2447
|
+
status: 'uploading',
|
|
2448
|
+
progress: fileProgress
|
|
2449
|
+
});
|
|
2450
|
+
var overallProgress = (fileIndex + event.loaded / event.total) / totalFiles * 100;
|
|
2451
|
+
showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');
|
|
2452
|
+
});
|
|
2453
|
+
xhr.addEventListener('load', function () {
|
|
2454
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
2455
|
+
try {
|
|
2456
|
+
resolve(JSON.parse(xhr.responseText));
|
|
2457
|
+
} catch (error) {
|
|
2458
|
+
reject(new Error('Upload failed: invalid server response.'));
|
|
2459
|
+
}
|
|
2460
|
+
return;
|
|
2461
|
+
}
|
|
2462
|
+
reject(new Error((xhr.responseText || 'Upload failed.').trim()));
|
|
2463
|
+
});
|
|
2464
|
+
xhr.addEventListener('error', function () {
|
|
2465
|
+
reject(new Error('Upload failed. Please check your connection and try again.'));
|
|
2466
|
+
});
|
|
2467
|
+
xhr.send(formData);
|
|
2468
|
+
});
|
|
2469
|
+
}
|
|
2470
|
+
function uploadDocuments(_x) {
|
|
2471
|
+
return _uploadDocuments.apply(this, arguments);
|
|
2472
|
+
}
|
|
2473
|
+
function _uploadDocuments() {
|
|
2474
|
+
_uploadDocuments = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(files) {
|
|
2475
|
+
var filesToUpload, duplicateItems, knownDocumentKeys, pendingItems, uploadedCount, failedUploads, i, file, pendingItem, result, uploaded, failed, missingUploadMessage, failedMessage, errorMessage, _t2, _t3;
|
|
2476
|
+
return _regenerator().w(function (_context6) {
|
|
2477
|
+
while (1) switch (_context6.p = _context6.n) {
|
|
2478
|
+
case 0:
|
|
2479
|
+
if (!(!config.uploadDocumentUrl || !files || files.length === 0)) {
|
|
2480
|
+
_context6.n = 1;
|
|
2481
|
+
break;
|
|
2482
|
+
}
|
|
2483
|
+
return _context6.a(2);
|
|
2484
|
+
case 1:
|
|
2485
|
+
if (!isUploadingDocuments) {
|
|
2486
|
+
_context6.n = 2;
|
|
2487
|
+
break;
|
|
2488
|
+
}
|
|
2489
|
+
showUploadStatus('A document upload is already in progress.', 'text-warning');
|
|
2490
|
+
return _context6.a(2);
|
|
2491
|
+
case 2:
|
|
2492
|
+
isUploadingDocuments = true;
|
|
2493
|
+
filesToUpload = [];
|
|
2494
|
+
duplicateItems = [];
|
|
2495
|
+
knownDocumentKeys = new Set(interactionDocuments.map(function (document) {
|
|
2496
|
+
return getDocumentKey(document.fileName, document.fileSize);
|
|
2497
|
+
}));
|
|
2498
|
+
Array.from(files).forEach(function (file) {
|
|
2499
|
+
if (isDuplicateFile(file, knownDocumentKeys)) {
|
|
2500
|
+
duplicateItems.push(file);
|
|
2501
|
+
return;
|
|
2502
|
+
}
|
|
2503
|
+
knownDocumentKeys.add(getDocumentKey(file.name, file.size));
|
|
2504
|
+
filesToUpload.push(file);
|
|
2505
|
+
});
|
|
2506
|
+
if (duplicateItems.length > 0) {
|
|
2507
|
+
uploadItems = uploadItems.concat(duplicateItems.map(function (file, index) {
|
|
2508
|
+
return Object.assign(createUploadItem(file, index), {
|
|
2509
|
+
status: 'failed',
|
|
2510
|
+
progress: 100,
|
|
2511
|
+
error: 'This document is already attached.'
|
|
2512
|
+
});
|
|
2513
|
+
}));
|
|
2514
|
+
renderUploadQueue();
|
|
2515
|
+
}
|
|
2516
|
+
if (!(filesToUpload.length === 0)) {
|
|
2517
|
+
_context6.n = 3;
|
|
2518
|
+
break;
|
|
2519
|
+
}
|
|
2520
|
+
isUploadingDocuments = false;
|
|
2521
|
+
showUploadStatus(duplicateItems.map(function (file) {
|
|
2522
|
+
return file.name + ': This document is already attached.';
|
|
2523
|
+
}).join(' | '), 'text-warning');
|
|
2524
|
+
showUploadProgress(null);
|
|
2525
|
+
return _context6.a(2);
|
|
2526
|
+
case 3:
|
|
2527
|
+
pendingItems = filesToUpload.map(createUploadItem);
|
|
2528
|
+
uploadItems = uploadItems.concat(pendingItems);
|
|
2529
|
+
renderUploadQueue();
|
|
2530
|
+
showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');
|
|
2531
|
+
fileInput.disabled = true;
|
|
2532
|
+
_context6.p = 4;
|
|
2533
|
+
uploadedCount = 0;
|
|
2534
|
+
failedUploads = duplicateItems.map(function (file) {
|
|
2535
|
+
return file.name + ': This document is already attached.';
|
|
2536
|
+
});
|
|
2537
|
+
i = 0;
|
|
2538
|
+
case 5:
|
|
2539
|
+
if (!(i < filesToUpload.length)) {
|
|
2540
|
+
_context6.n = 10;
|
|
2541
|
+
break;
|
|
2542
|
+
}
|
|
2543
|
+
file = filesToUpload[i];
|
|
2544
|
+
pendingItem = pendingItems[i];
|
|
2545
|
+
updateUploadItem(pendingItem.id, {
|
|
2546
|
+
status: 'uploading',
|
|
2547
|
+
progress: 0,
|
|
2548
|
+
error: null
|
|
2549
|
+
});
|
|
2550
|
+
showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');
|
|
2551
|
+
_context6.p = 6;
|
|
2552
|
+
_context6.n = 7;
|
|
2553
|
+
return uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);
|
|
2554
|
+
case 7:
|
|
2555
|
+
result = _context6.v;
|
|
2556
|
+
uploaded = (Array.isArray(result.uploaded) ? result.uploaded : []).map(normalizeDocumentInfo).filter(function (document) {
|
|
2557
|
+
return document && document.documentId;
|
|
2558
|
+
});
|
|
2559
|
+
failed = Array.isArray(result.failed) ? result.failed : [];
|
|
2560
|
+
if (uploaded.length > 0) {
|
|
2561
|
+
uploadedCount += uploaded.length;
|
|
2562
|
+
interactionDocuments = interactionDocuments.concat(uploaded);
|
|
2563
|
+
updateUploadItem(pendingItem.id, {
|
|
2564
|
+
status: 'uploaded',
|
|
2565
|
+
progress: 100,
|
|
2566
|
+
error: null
|
|
2567
|
+
});
|
|
2568
|
+
} else {
|
|
2569
|
+
missingUploadMessage = failed.length > 0 ? failed.map(function (entry) {
|
|
2570
|
+
return entry.fileName + ': ' + entry.error;
|
|
2571
|
+
}).join(' | ') : 'The server did not confirm that the file was uploaded.';
|
|
2572
|
+
if (failed.length === 0) {
|
|
2573
|
+
failedUploads.push(missingUploadMessage);
|
|
2574
|
+
}
|
|
2575
|
+
updateUploadItem(pendingItem.id, {
|
|
2576
|
+
status: 'failed',
|
|
2577
|
+
progress: 100,
|
|
2578
|
+
error: missingUploadMessage
|
|
2579
|
+
});
|
|
2580
|
+
}
|
|
2581
|
+
if (failed.length > 0) {
|
|
2582
|
+
failedMessage = failed.map(function (entry) {
|
|
2583
|
+
return entry.fileName + ': ' + entry.error;
|
|
2584
|
+
}).join(' | ');
|
|
2585
|
+
failedUploads.push(failedMessage);
|
|
2586
|
+
updateUploadItem(pendingItem.id, {
|
|
2587
|
+
status: 'failed',
|
|
2588
|
+
progress: 100,
|
|
2589
|
+
error: failedMessage
|
|
2590
|
+
});
|
|
2591
|
+
}
|
|
2592
|
+
_context6.n = 9;
|
|
2593
|
+
break;
|
|
2594
|
+
case 8:
|
|
2595
|
+
_context6.p = 8;
|
|
2596
|
+
_t2 = _context6.v;
|
|
2597
|
+
errorMessage = _t2 && _t2.message ? _t2.message : 'Upload failed. Please try again.';
|
|
2598
|
+
console.error('Upload failed:', _t2);
|
|
2599
|
+
failedUploads.push(file.name + ': ' + errorMessage);
|
|
2600
|
+
updateUploadItem(pendingItem.id, {
|
|
2601
|
+
status: 'failed',
|
|
2602
|
+
progress: pendingItem.progress || 0,
|
|
2603
|
+
error: errorMessage
|
|
2604
|
+
});
|
|
2605
|
+
case 9:
|
|
2606
|
+
i++;
|
|
2607
|
+
_context6.n = 5;
|
|
2608
|
+
break;
|
|
2609
|
+
case 10:
|
|
2610
|
+
renderDocuments();
|
|
2611
|
+
if (!(failedUploads.length > 0)) {
|
|
2612
|
+
_context6.n = 11;
|
|
2613
|
+
break;
|
|
2614
|
+
}
|
|
2615
|
+
removeUploadItems(function (item) {
|
|
2616
|
+
return item.status === 'uploaded';
|
|
2617
|
+
});
|
|
2618
|
+
showUploadStatus((uploadedCount > 0 ? 'Uploaded ' + uploadedCount + ' document(s). ' : '') + failedUploads.join(' | '), uploadedCount > 0 ? 'text-warning' : 'text-danger');
|
|
2619
|
+
showUploadProgress(null);
|
|
2620
|
+
return _context6.a(2);
|
|
2621
|
+
case 11:
|
|
2622
|
+
removeUploadItems(function () {
|
|
2623
|
+
return true;
|
|
2624
|
+
});
|
|
2625
|
+
showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');
|
|
2626
|
+
showUploadProgress(null);
|
|
2627
|
+
_context6.n = 13;
|
|
2628
|
+
break;
|
|
2629
|
+
case 12:
|
|
2630
|
+
_context6.p = 12;
|
|
2631
|
+
_t3 = _context6.v;
|
|
2632
|
+
console.error('Upload failed:', _t3);
|
|
2633
|
+
showUploadStatus('Upload failed. Please try again.', 'text-danger');
|
|
2634
|
+
showUploadProgress(null);
|
|
2635
|
+
case 13:
|
|
2636
|
+
_context6.p = 13;
|
|
2637
|
+
isUploadingDocuments = false;
|
|
2638
|
+
fileInput.disabled = false;
|
|
2639
|
+
fileInput.value = '';
|
|
2640
|
+
return _context6.f(13);
|
|
2641
|
+
case 14:
|
|
2642
|
+
return _context6.a(2);
|
|
2643
|
+
}
|
|
2644
|
+
}, _callee6, null, [[6, 8], [4, 12, 13, 14]]);
|
|
2645
|
+
}));
|
|
2646
|
+
return _uploadDocuments.apply(this, arguments);
|
|
2647
|
+
}
|
|
2648
|
+
function removeDocument(_x2) {
|
|
2649
|
+
return _removeDocument.apply(this, arguments);
|
|
2650
|
+
}
|
|
2651
|
+
function _removeDocument() {
|
|
2652
|
+
_removeDocument = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7(documentId) {
|
|
2653
|
+
var response, result, serverDocuments, _t4, _t5;
|
|
2654
|
+
return _regenerator().w(function (_context7) {
|
|
2655
|
+
while (1) switch (_context7.p = _context7.n) {
|
|
2656
|
+
case 0:
|
|
2657
|
+
if (!(!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?'))) {
|
|
2658
|
+
_context7.n = 1;
|
|
2659
|
+
break;
|
|
2660
|
+
}
|
|
2661
|
+
return _context7.a(2);
|
|
2662
|
+
case 1:
|
|
2663
|
+
_context7.p = 1;
|
|
2664
|
+
_context7.n = 2;
|
|
2665
|
+
return fetch(config.removeDocumentUrl, {
|
|
2666
|
+
method: 'POST',
|
|
2667
|
+
headers: {
|
|
2668
|
+
'Content-Type': 'application/json'
|
|
2669
|
+
},
|
|
2670
|
+
body: JSON.stringify({
|
|
2671
|
+
itemId: config.itemId,
|
|
2672
|
+
documentId: documentId
|
|
2673
|
+
})
|
|
2674
|
+
});
|
|
2675
|
+
case 2:
|
|
2676
|
+
response = _context7.v;
|
|
2677
|
+
if (response.ok) {
|
|
2678
|
+
_context7.n = 4;
|
|
2679
|
+
break;
|
|
2680
|
+
}
|
|
2681
|
+
_t4 = console;
|
|
2682
|
+
_context7.n = 3;
|
|
2683
|
+
return response.text();
|
|
2684
|
+
case 3:
|
|
2685
|
+
_t4.error.call(_t4, 'Failed to remove document:', _context7.v);
|
|
2686
|
+
showUploadStatus('Failed to remove document.', 'text-danger');
|
|
2687
|
+
return _context7.a(2);
|
|
2688
|
+
case 4:
|
|
2689
|
+
_context7.n = 5;
|
|
2690
|
+
return response.json();
|
|
2691
|
+
case 5:
|
|
2692
|
+
result = _context7.v;
|
|
2693
|
+
serverDocuments = (Array.isArray(result.documents) ? result.documents : []).map(normalizeDocumentInfo).filter(function (document) {
|
|
2694
|
+
return document && document.documentId;
|
|
2695
|
+
});
|
|
2696
|
+
interactionDocuments = serverDocuments.length > 0 ? serverDocuments : interactionDocuments.filter(function (document) {
|
|
2697
|
+
return document.documentId !== documentId;
|
|
2698
|
+
});
|
|
2699
|
+
renderDocuments();
|
|
2700
|
+
showUploadStatus('Document removed.', 'text-success');
|
|
2701
|
+
_context7.n = 7;
|
|
2702
|
+
break;
|
|
2703
|
+
case 6:
|
|
2704
|
+
_context7.p = 6;
|
|
2705
|
+
_t5 = _context7.v;
|
|
2706
|
+
console.error('Remove failed:', _t5);
|
|
2707
|
+
showUploadStatus('Failed to remove document.', 'text-danger');
|
|
2708
|
+
case 7:
|
|
2709
|
+
return _context7.a(2);
|
|
2710
|
+
}
|
|
2711
|
+
}, _callee7, null, [[1, 6]]);
|
|
2712
|
+
}));
|
|
2713
|
+
return _removeDocument.apply(this, arguments);
|
|
2714
|
+
}
|
|
2715
|
+
var onFileInputChange = function onFileInputChange(event) {
|
|
2716
|
+
var selectedFiles = event.target.files ? Array.from(event.target.files) : [];
|
|
2717
|
+
uploadDocuments(selectedFiles);
|
|
2718
|
+
};
|
|
2719
|
+
fileInput.addEventListener('change', onFileInputChange);
|
|
2720
|
+
fileInput[managerStateKey] = {
|
|
2721
|
+
dispose: function dispose() {
|
|
2722
|
+
fileInput.removeEventListener('change', onFileInputChange);
|
|
2723
|
+
}
|
|
2724
|
+
};
|
|
2725
|
+
renderDocuments();
|
|
2726
|
+
renderUploadQueue();
|
|
2727
|
+
showUploadStatus(null);
|
|
2728
|
+
showUploadProgress(null);
|
|
2729
|
+
}
|
|
2730
|
+
return {
|
|
2731
|
+
initialize: initialize
|
|
2732
|
+
};
|
|
2733
|
+
}();
|
|
2096
2734
|
|
|
2097
2735
|
// Download chart as image via event delegation (DOMPurify strips inline onclick).
|
|
2098
2736
|
document.addEventListener('click', function (e) {
|