@crestapps/ai-chat-ui 1.0.0-preview.16 → 1.0.0-preview.19

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.
@@ -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
- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
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)\"><span :class=\"getAssistantIcon(message)\"></span></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 }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <span :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></span>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message.content)\" title=\"Click here to copy response to clipboard.\">\n <span class=\"fa-solid fa-copy\"></span>\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 <span v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></span>\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 <span class=\"fa-solid fa-xmark\"></span>\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 <span v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></span>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n ",
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)\"><span :class=\"getAssistantIcon(message)\"></span></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 <span :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></span>\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 <span class=\"fa-solid fa-copy\"></span>\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 <span v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></span>\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 <span class=\"fa-solid fa-xmark\"></span>\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 <span v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></span>\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\"><span class=\"fa fa-robot\" style=\"display: inline-block;\"></span></span>\n Assistant\n </div>\n ",
35
38
  // Localizable strings
36
39
  untitledText: 'Untitled',
@@ -56,6 +59,164 @@ window.chatInteractionManager = function () {
56
59
  span.textContent = text;
57
60
  return span.innerHTML;
58
61
  }
62
+ function normalizeReference(reference) {
63
+ var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$title, _ref4, _normalized$link, _ref5, _normalized$reference;
64
+ if (!reference || _typeof(reference) !== 'object') {
65
+ return null;
66
+ }
67
+ var normalized = Object.assign({}, reference);
68
+ normalized.index = (_ref = (_normalized$index = normalized.index) !== null && _normalized$index !== void 0 ? _normalized$index : normalized.Index) !== null && _ref !== void 0 ? _ref : 0;
69
+ normalized.text = (_ref2 = (_normalized$text = normalized.text) !== null && _normalized$text !== void 0 ? _normalized$text : normalized.Text) !== null && _ref2 !== void 0 ? _ref2 : null;
70
+ normalized.title = (_ref3 = (_normalized$title = normalized.title) !== null && _normalized$title !== void 0 ? _normalized$title : normalized.Title) !== null && _ref3 !== void 0 ? _ref3 : null;
71
+ normalized.link = sanitizeUrl((_ref4 = (_normalized$link = normalized.link) !== null && _normalized$link !== void 0 ? _normalized$link : normalized.Link) !== null && _ref4 !== void 0 ? _ref4 : null);
72
+ normalized.referenceType = (_ref5 = (_normalized$reference = normalized.referenceType) !== null && _normalized$reference !== void 0 ? _normalized$reference : normalized.ReferenceType) !== null && _ref5 !== void 0 ? _ref5 : null;
73
+ return normalized;
74
+ }
75
+ function isDownloadCitationReference(reference) {
76
+ if (!reference || _typeof(reference) !== 'object') {
77
+ return false;
78
+ }
79
+ if (typeof reference.referenceType === 'string' && reference.referenceType.toLowerCase() === 'document') {
80
+ return true;
81
+ }
82
+ if (typeof reference.link === 'string' && /\/ai\/documents\/.+\/download(?:$|\?)/i.test(reference.link)) {
83
+ return true;
84
+ }
85
+ return false;
86
+ }
87
+ function normalizeReferences(references) {
88
+ if (!references || _typeof(references) !== 'object') {
89
+ return {};
90
+ }
91
+ var normalized = {};
92
+ for (var _i = 0, _Object$entries = Object.entries(references); _i < _Object$entries.length; _i++) {
93
+ var _normalizeReference;
94
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
95
+ key = _Object$entries$_i[0],
96
+ value = _Object$entries$_i[1];
97
+ normalized[key] = (_normalizeReference = normalizeReference(value)) !== null && _normalizeReference !== void 0 ? _normalizeReference : {};
98
+ }
99
+ return normalized;
100
+ }
101
+ function getCitationLabel(reference, key) {
102
+ return reference.title || reference.text || key;
103
+ }
104
+ function buildCitationDisplay(content, references) {
105
+ var processedContent = (content || '').trim();
106
+ var messageReferences = normalizeReferences(references);
107
+ if (!processedContent || !Object.keys(messageReferences).length) {
108
+ return {
109
+ content: processedContent,
110
+ citations: []
111
+ };
112
+ }
113
+ var citedRefs = Object.entries(messageReferences).filter(function (_ref6) {
114
+ var _ref7 = _slicedToArray(_ref6, 1),
115
+ key = _ref7[0];
116
+ return processedContent.includes(key);
117
+ });
118
+ if (!citedRefs.length) {
119
+ return {
120
+ content: processedContent,
121
+ citations: []
122
+ };
123
+ }
124
+ citedRefs.sort(function (_ref8, _ref9) {
125
+ var _ref0 = _slicedToArray(_ref8, 2),
126
+ a = _ref0[1];
127
+ var _ref1 = _slicedToArray(_ref9, 2),
128
+ b = _ref1[1];
129
+ return a.index - b.index;
130
+ });
131
+ var citations = [];
132
+ var displayIndex = 1;
133
+ var _iterator = _createForOfIteratorHelper(citedRefs),
134
+ _step;
135
+ try {
136
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
137
+ var _step$value = _slicedToArray(_step.value, 2),
138
+ key = _step$value[0],
139
+ value = _step$value[1];
140
+ var placeholder = "__CITE_".concat(displayIndex, "_").concat(value.index || displayIndex, "__");
141
+ processedContent = processedContent.replaceAll(key, placeholder);
142
+ citations.push({
143
+ referenceKey: key,
144
+ displayIndex: displayIndex,
145
+ label: getCitationLabel(value, key),
146
+ link: value.link || null,
147
+ isDownload: isDownloadCitationReference(value),
148
+ placeholder: placeholder
149
+ });
150
+ displayIndex++;
151
+ }
152
+ } catch (err) {
153
+ _iterator.e(err);
154
+ } finally {
155
+ _iterator.f();
156
+ }
157
+ for (var _i2 = 0, _citations = citations; _i2 < _citations.length; _i2++) {
158
+ var citation = _citations[_i2];
159
+ processedContent = processedContent.replaceAll(citation.placeholder, "<sup>".concat(citation.displayIndex, "</sup>"));
160
+ }
161
+ processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');
162
+ return {
163
+ content: processedContent,
164
+ citations: citations.map(function (_ref10) {
165
+ var placeholder = _ref10.placeholder,
166
+ citation = _objectWithoutProperties(_ref10, _excluded);
167
+ return citation;
168
+ })
169
+ };
170
+ }
171
+ function buildCopyContent(content, citations) {
172
+ var copyContent = (content || '').trim();
173
+ if (!copyContent || !Array.isArray(citations) || citations.length === 0) {
174
+ return copyContent;
175
+ }
176
+ var _iterator2 = _createForOfIteratorHelper(citations),
177
+ _step2;
178
+ try {
179
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
180
+ var citation = _step2.value;
181
+ copyContent = copyContent.replaceAll(citation.referenceKey, "[".concat(citation.displayIndex, "]"));
182
+ }
183
+ } catch (err) {
184
+ _iterator2.e(err);
185
+ } finally {
186
+ _iterator2.f();
187
+ }
188
+ copyContent += '\n\nReferences:\n';
189
+ var _iterator3 = _createForOfIteratorHelper(citations),
190
+ _step3;
191
+ try {
192
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
193
+ var _citation = _step3.value;
194
+ copyContent += "".concat(_citation.displayIndex, ". ").concat(_citation.label);
195
+ if (_citation.link) {
196
+ copyContent += " - ".concat(_citation.link);
197
+ }
198
+ copyContent += '\n';
199
+ }
200
+ } catch (err) {
201
+ _iterator3.e(err);
202
+ } finally {
203
+ _iterator3.f();
204
+ }
205
+ return copyContent.trimEnd();
206
+ }
207
+ function updateMessagePresentation(message, references) {
208
+ var messageReferences = normalizeReferences(references !== null && references !== void 0 ? references : message.references);
209
+ var rawContent = typeof message.rawContent === 'string' ? message.rawContent : typeof message.content === 'string' ? message.content : '';
210
+ var citationDisplay = buildCitationDisplay(rawContent, messageReferences);
211
+ message.rawContent = rawContent;
212
+ message.content = rawContent;
213
+ message.displayContent = citationDisplay.content;
214
+ message.references = messageReferences;
215
+ message.citationReferences = citationDisplay.citations;
216
+ message.copyContent = buildCopyContent(rawContent, citationDisplay.citations);
217
+ message.htmlContent = parseMarkdownContent(citationDisplay.content, message);
218
+ return message;
219
+ }
59
220
  var renderer = new marked.Renderer();
60
221
 
61
222
  // Modify the link rendering to open in a new tab
@@ -219,11 +380,11 @@ window.chatInteractionManager = function () {
219
380
  // Defer to requestAnimationFrame so the browser has fully laid out the
220
381
  // canvas elements before Chart.js reads their dimensions.
221
382
  requestAnimationFrame(function () {
222
- var _iterator = _createForOfIteratorHelper(charts),
223
- _step;
383
+ var _iterator4 = _createForOfIteratorHelper(charts),
384
+ _step4;
224
385
  try {
225
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
226
- var c = _step.value;
386
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
387
+ var c = _step4.value;
227
388
  var canvas = document.getElementById(c.chartId);
228
389
  if (!canvas) {
229
390
  continue;
@@ -256,9 +417,9 @@ window.chatInteractionManager = function () {
256
417
  }
257
418
  }
258
419
  } catch (err) {
259
- _iterator.e(err);
420
+ _iterator4.e(err);
260
421
  } finally {
261
- _iterator.f();
422
+ _iterator4.f();
262
423
  }
263
424
  });
264
425
  }
@@ -467,7 +628,7 @@ window.chatInteractionManager = function () {
467
628
  _this.scrollToBottom();
468
629
  }
469
630
  });
470
- _this.connection.on("ReceiveConversationAssistantToken", function (itemId, messageId, token, responseId, appearance) {
631
+ _this.connection.on("ReceiveConversationAssistantToken", function (itemId, messageId, token, responseId, references, appearance) {
471
632
  if (!_this._conversationAssistantMessage) {
472
633
  _this.stopAudio();
473
634
  _this.hideTypingIndicator();
@@ -485,7 +646,8 @@ window.chatInteractionManager = function () {
485
646
  content: "",
486
647
  htmlContent: "",
487
648
  isStreaming: true,
488
- appearance: _this.normalizeAssistantAppearance(appearance)
649
+ appearance: _this.normalizeAssistantAppearance(appearance),
650
+ references: {}
489
651
  };
490
652
  _this.messages.push(newMessage);
491
653
  _this._conversationAssistantMessage = {
@@ -499,19 +661,22 @@ window.chatInteractionManager = function () {
499
661
  if (!msg.appearance) {
500
662
  msg.appearance = _this.normalizeAssistantAppearance(appearance);
501
663
  }
502
- msg.content = _this._conversationAssistantMessage.content;
503
- msg.htmlContent = parseMarkdownContent(msg.content, msg);
664
+ msg.rawContent = _this._conversationAssistantMessage.content;
665
+ msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));
666
+ updateMessagePresentation(msg, msg.references);
504
667
  _this.$nextTick(function () {
505
668
  renderChartsInMessage(msg);
506
669
  _this.scrollToBottom();
507
670
  });
508
671
  }
509
672
  });
510
- _this.connection.on("ReceiveConversationAssistantComplete", function (itemId, messageId) {
673
+ _this.connection.on("ReceiveConversationAssistantComplete", function (itemId, messageId, references) {
511
674
  if (_this._conversationAssistantMessage) {
512
675
  var msg = _this.messages[_this._conversationAssistantMessage.index];
513
676
  if (msg) {
514
677
  msg.isStreaming = false;
678
+ msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));
679
+ updateMessagePresentation(msg, msg.references);
515
680
  }
516
681
  _this._conversationAssistantMessage = null;
517
682
  }
@@ -605,79 +770,9 @@ window.chatInteractionManager = function () {
605
770
  addMessage: function addMessage(message) {
606
771
  var _this3 = this;
607
772
  if (message.content) {
608
- var processedContent = message.content.trim();
609
- if (message.references && _typeof(message.references) === "object" && Object.keys(message.references).length) {
610
- // Only include references that were actually cited in the response.
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);
773
+ var _message$rawContent;
774
+ message.rawContent = (_message$rawContent = message.rawContent) !== null && _message$rawContent !== void 0 ? _message$rawContent : message.content;
775
+ updateMessagePresentation(message, message.references);
681
776
  }
682
777
  this.addMessageInternal(message);
683
778
  this.hidePlaceholder();
@@ -828,11 +923,12 @@ window.chatInteractionManager = function () {
828
923
  message = newMessage;
829
924
  }
830
925
  if (chunk.references && _typeof(chunk.references) === "object" && Object.keys(chunk.references).length) {
831
- for (var _i = 0, _Object$entries = Object.entries(chunk.references); _i < _Object$entries.length; _i++) {
832
- var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
833
- key = _Object$entries$_i[0],
834
- value = _Object$entries$_i[1];
835
- references[key] = value;
926
+ for (var _i3 = 0, _Object$entries2 = Object.entries(chunk.references); _i3 < _Object$entries2.length; _i3++) {
927
+ var _normalizeReference2;
928
+ var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i3], 2),
929
+ key = _Object$entries2$_i[0],
930
+ value = _Object$entries2$_i[1];
931
+ references[key] = (_normalizeReference2 = normalizeReference(value)) !== null && _normalizeReference2 !== void 0 ? _normalizeReference2 : {};
836
932
  }
837
933
  }
838
934
  if (chunk.content) {
@@ -844,17 +940,10 @@ window.chatInteractionManager = function () {
844
940
  if (chunk.responseId) {
845
941
  lastResponseId = chunk.responseId;
846
942
  }
847
- var processedContent = chunk.content;
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>');
943
+ content += chunk.content;
855
944
  }
856
- message.content = content;
857
- message.htmlContent = parseMarkdownContent(content, message);
945
+ message.rawContent = content;
946
+ updateMessagePresentation(message, references);
858
947
  _this5.messages[messageIndex] = message;
859
948
  _this5.$nextTick(function () {
860
949
  renderChartsInMessage(message);
@@ -908,86 +997,12 @@ window.chatInteractionManager = function () {
908
997
  },
909
998
  processReferences: function processReferences(references, messageIndex) {
910
999
  var _this6 = this;
1000
+ references = normalizeReferences(references);
911
1001
  if (Object.keys(references).length) {
1002
+ var _ref11, _message$rawContent2;
912
1003
  var message = this.messages[messageIndex];
913
- var content = message.content || '';
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);
1004
+ message.rawContent = (_ref11 = (_message$rawContent2 = message.rawContent) !== null && _message$rawContent2 !== void 0 ? _message$rawContent2 : message.content) !== null && _ref11 !== void 0 ? _ref11 : '';
1005
+ updateMessagePresentation(message, references);
991
1006
  this.messages[messageIndex] = message;
992
1007
  this.$nextTick(function () {
993
1008
  renderChartsInMessage(message);
@@ -1113,18 +1128,18 @@ window.chatInteractionManager = function () {
1113
1128
  }, 0);
1114
1129
  var combined = new Uint8Array(totalLength);
1115
1130
  var offset = 0;
1116
- var _iterator8 = _createForOfIteratorHelper(this.audioChunks),
1117
- _step8;
1131
+ var _iterator5 = _createForOfIteratorHelper(this.audioChunks),
1132
+ _step5;
1118
1133
  try {
1119
- for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
1120
- var chunk = _step8.value;
1134
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
1135
+ var chunk = _step5.value;
1121
1136
  combined.set(chunk, offset);
1122
1137
  offset += chunk.length;
1123
1138
  }
1124
1139
  } catch (err) {
1125
- _iterator8.e(err);
1140
+ _iterator5.e(err);
1126
1141
  } finally {
1127
- _iterator8.f();
1142
+ _iterator5.f();
1128
1143
  }
1129
1144
  this.audioChunks = [];
1130
1145
  var blob = new Blob([combined], {
@@ -1562,7 +1577,7 @@ window.chatInteractionManager = function () {
1562
1577
  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["])');
1563
1578
  },
1564
1579
  getSelectedGroupValues: function getSelectedGroupValues(groupName, fallbackSelector) {
1565
- var explicitSelections = document.querySelectorAll(".capability-checkbox[data-save-group=\"".concat(groupName, "\"]:checked"));
1580
+ var explicitSelections = document.querySelectorAll(".capability-checkbox[data-save-group=\"".concat(groupName, "\"]:checked, .capability-checkbox[data-group=\"").concat(groupName, "\"]:checked"));
1566
1581
  if (explicitSelections.length > 0) {
1567
1582
  var _values = [];
1568
1583
  explicitSelections.forEach(function (checkbox) {
@@ -1758,8 +1773,8 @@ window.chatInteractionManager = function () {
1758
1773
  _this17.loadInteraction(itemId);
1759
1774
  });
1760
1775
  }
1761
- for (var _i3 = 0; _i3 < config.messages.length; _i3++) {
1762
- this.addMessage(config.messages[_i3]);
1776
+ for (var _i4 = 0; _i4 < config.messages.length; _i4++) {
1777
+ this.addMessage(config.messages[_i4]);
1763
1778
  }
1764
1779
 
1765
1780
  // Delegate click for code block copy buttons.
@@ -1791,7 +1806,7 @@ window.chatInteractionManager = function () {
1791
1806
  }
1792
1807
  });
1793
1808
  document.addEventListener('change', function (event) {
1794
- if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .group-toggle, .ci-agent-global-toggle')) {
1809
+ if (event.target.matches('.setting-input[data-setting], .capability-checkbox[data-save-group], .capability-checkbox[data-group], .group-toggle, .ci-agent-global-toggle')) {
1795
1810
  if (event.target.matches('.setting-input[data-setting]')) {
1796
1811
  _this17.validateSettingInput(event.target);
1797
1812
  }
@@ -1856,26 +1871,35 @@ window.chatInteractionManager = function () {
1856
1871
  },
1857
1872
  clearHistory: function clearHistory(itemId) {
1858
1873
  var self = this;
1859
- confirmDialog({
1860
- title: config.clearHistoryTitle,
1861
- message: config.clearHistoryMessage,
1862
- okText: config.clearHistoryOkText,
1863
- cancelText: config.clearHistoryCancelText,
1864
- callback: function callback(confirmed) {
1865
- if (confirmed) {
1866
- // Cancel any active stream before clearing history.
1867
- if (self.stream) {
1868
- self.stream.dispose();
1869
- self.stream = null;
1870
- self.hideTypingIndicator();
1871
- self.streamingFinished();
1874
+ var clearHistoryConfirmed = function clearHistoryConfirmed() {
1875
+ // Cancel any active stream before clearing history.
1876
+ if (self.stream) {
1877
+ self.stream.dispose();
1878
+ self.stream = null;
1879
+ self.hideTypingIndicator();
1880
+ self.streamingFinished();
1881
+ }
1882
+ self.connection.invoke("ClearHistory", itemId)["catch"](function (err) {
1883
+ return console.error('Error clearing history:', err);
1884
+ });
1885
+ };
1886
+ if (typeof confirmDialog === 'function') {
1887
+ confirmDialog({
1888
+ title: config.clearHistoryTitle,
1889
+ message: config.clearHistoryMessage,
1890
+ okText: config.clearHistoryOkText,
1891
+ cancelText: config.clearHistoryCancelText,
1892
+ callback: function callback(confirmed) {
1893
+ if (confirmed) {
1894
+ clearHistoryConfirmed();
1872
1895
  }
1873
- self.connection.invoke("ClearHistory", itemId)["catch"](function (err) {
1874
- return console.error('Error clearing history:', err);
1875
- });
1876
1896
  }
1877
- }
1878
- });
1897
+ });
1898
+ return;
1899
+ }
1900
+ if (window.confirm(config.clearHistoryMessage || 'Clear all messages?')) {
1901
+ clearHistoryConfirmed();
1902
+ }
1879
1903
  },
1880
1904
  debouncedSaveSettings: function debouncedSaveSettings() {
1881
1905
  var _this18 = this;
@@ -1981,7 +2005,9 @@ window.chatInteractionManager = function () {
1981
2005
  this.isInteractionStarted = true;
1982
2006
  },
1983
2007
  copyResponse: function copyResponse(message) {
1984
- navigator.clipboard.writeText(message);
2008
+ var _ref13, _message$copyContent;
2009
+ 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 : '';
2010
+ navigator.clipboard.writeText(text);
1985
2011
  },
1986
2012
  startRecording: function startRecording() {
1987
2013
  var _this20 = this;
@@ -2132,6 +2158,535 @@ window.chatInteractionManager = function () {
2132
2158
  initialize: initialize
2133
2159
  };
2134
2160
  }();
2161
+ window.chatInteractionDocumentManager = function () {
2162
+ var managerStateKey = '__chatInteractionDocumentManagerState';
2163
+ function normalizeDocumentInfo(document) {
2164
+ if (!document || _typeof(document) !== 'object') {
2165
+ return null;
2166
+ }
2167
+ return {
2168
+ documentId: document.documentId || document.DocumentId || '',
2169
+ fileName: document.fileName || document.FileName || '',
2170
+ fileSize: document.fileSize || document.FileSize || 0
2171
+ };
2172
+ }
2173
+ function formatFileSize(bytes) {
2174
+ if (!bytes || bytes < 1024) {
2175
+ return (bytes || 0) + ' B';
2176
+ }
2177
+ if (bytes < 1024 * 1024) {
2178
+ return (bytes / 1024).toFixed(1) + ' KB';
2179
+ }
2180
+ return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
2181
+ }
2182
+ function getDocumentKey(fileName, fileSize) {
2183
+ return (fileName || '').trim().toLowerCase() + '::' + (fileSize || 0);
2184
+ }
2185
+ function isDuplicateFile(file, knownKeys) {
2186
+ return knownKeys.has(getDocumentKey(file.name, file.size));
2187
+ }
2188
+ function getDocumentsFromDom(container) {
2189
+ if (!container) {
2190
+ return [];
2191
+ }
2192
+ return Array.from(container.querySelectorAll('[data-chat-document-id]')).map(function (element) {
2193
+ return normalizeDocumentInfo({
2194
+ documentId: element.dataset.chatDocumentId,
2195
+ fileName: element.dataset.chatDocumentName,
2196
+ fileSize: Number(element.dataset.chatDocumentSize || 0)
2197
+ });
2198
+ }).filter(function (document) {
2199
+ return document && document.documentId;
2200
+ });
2201
+ }
2202
+ function initialize(config) {
2203
+ if (!config || !config.itemId) {
2204
+ return;
2205
+ }
2206
+ var fileInput = document.getElementById('chat-doc-upload');
2207
+ var documentsList = document.getElementById('chat-documents-list');
2208
+ var status = document.getElementById('chat-doc-upload-status');
2209
+ var progressContainer = document.getElementById('chat-doc-upload-progress');
2210
+ var progressBar = document.getElementById('chat-doc-upload-progress-bar');
2211
+ var uploadQueue = document.getElementById('chat-doc-upload-queue');
2212
+ if (!fileInput || !documentsList || !status || !progressContainer || !progressBar || !uploadQueue) {
2213
+ return;
2214
+ }
2215
+ var previousState = fileInput[managerStateKey];
2216
+ if (previousState && typeof previousState.dispose === 'function') {
2217
+ previousState.dispose();
2218
+ }
2219
+ var interactionDocuments = (Array.isArray(config.existingDocuments) ? config.existingDocuments : []).map(normalizeDocumentInfo).filter(function (document) {
2220
+ return document && document.documentId;
2221
+ });
2222
+ if (interactionDocuments.length === 0) {
2223
+ interactionDocuments = getDocumentsFromDom(documentsList);
2224
+ }
2225
+ var uploadItems = [];
2226
+ var isUploadingDocuments = false;
2227
+ function createTextElement(tagName, className, text) {
2228
+ var element = document.createElement(tagName);
2229
+ if (className) {
2230
+ element.className = className;
2231
+ }
2232
+ element.textContent = text;
2233
+ return element;
2234
+ }
2235
+ function renderDocuments() {
2236
+ documentsList.innerHTML = '';
2237
+ if (interactionDocuments.length === 0) {
2238
+ documentsList.appendChild(createTextElement('div', 'text-muted small', 'No documents uploaded yet.'));
2239
+ return;
2240
+ }
2241
+ interactionDocuments.forEach(function (documentInfo) {
2242
+ var row = window.document.createElement('div');
2243
+ row.className = 'd-flex justify-content-between align-items-start gap-2 border rounded px-2 py-2 bg-white chat-document-row';
2244
+ row.dataset.chatDocumentId = documentInfo.documentId;
2245
+ row.dataset.chatDocumentName = documentInfo.fileName;
2246
+ row.dataset.chatDocumentSize = documentInfo.fileSize;
2247
+ var details = window.document.createElement('div');
2248
+ details.className = 'me-2 min-w-0';
2249
+ var name = createTextElement('div', 'fw-semibold small', documentInfo.fileName || 'Document');
2250
+ var icon = window.document.createElement('i');
2251
+ icon.className = 'bi bi-file-earmark-text me-1';
2252
+ name.prepend(icon);
2253
+ var size = createTextElement('div', 'text-muted small', formatFileSize(documentInfo.fileSize));
2254
+ details.appendChild(name);
2255
+ details.appendChild(size);
2256
+ var removeButton = createTextElement('button', 'btn btn-sm btn-outline-danger remove-chat-document-btn', ' Remove');
2257
+ removeButton.type = 'button';
2258
+ removeButton.dataset.documentId = documentInfo.documentId;
2259
+ var removeIcon = window.document.createElement('i');
2260
+ removeIcon.className = 'bi bi-trash';
2261
+ removeButton.prepend(removeIcon);
2262
+ removeButton.addEventListener('click', function () {
2263
+ return removeDocument(documentInfo.documentId);
2264
+ });
2265
+ row.appendChild(details);
2266
+ row.appendChild(removeButton);
2267
+ documentsList.appendChild(row);
2268
+ });
2269
+ }
2270
+ function showUploadStatus(message, cssClass) {
2271
+ if (!message) {
2272
+ status.textContent = '';
2273
+ status.className = 'small mt-2 d-none';
2274
+ return;
2275
+ }
2276
+ status.textContent = message;
2277
+ status.className = 'small mt-2 ' + (cssClass || 'text-muted');
2278
+ }
2279
+ function showUploadProgress(progress, message, cssClass) {
2280
+ if (progress === null || progress === undefined) {
2281
+ progressContainer.className = 'progress mt-2 d-none';
2282
+ progressContainer.setAttribute('aria-valuenow', '0');
2283
+ progressBar.className = 'progress-bar progress-bar-striped progress-bar-animated';
2284
+ progressBar.style.width = '0%';
2285
+ progressBar.textContent = '0%';
2286
+ return;
2287
+ }
2288
+ var roundedProgress = Math.max(0, Math.min(100, Math.round(progress)));
2289
+ progressContainer.className = 'progress mt-2';
2290
+ progressContainer.setAttribute('aria-valuenow', roundedProgress.toString());
2291
+ progressBar.className = 'progress-bar ' + (cssClass || 'progress-bar-striped progress-bar-animated');
2292
+ progressBar.style.width = roundedProgress + '%';
2293
+ progressBar.textContent = message || roundedProgress + '%';
2294
+ }
2295
+ function getUploadStatePresentation(state) {
2296
+ switch (state) {
2297
+ case 'uploaded':
2298
+ return {
2299
+ label: 'Uploaded',
2300
+ badgeClass: 'text-bg-success',
2301
+ progressClass: 'bg-success'
2302
+ };
2303
+ case 'failed':
2304
+ return {
2305
+ label: 'Failed',
2306
+ badgeClass: 'text-bg-danger',
2307
+ progressClass: 'bg-danger'
2308
+ };
2309
+ case 'uploading':
2310
+ return {
2311
+ label: 'Uploading',
2312
+ badgeClass: 'text-bg-warning',
2313
+ progressClass: 'bg-warning progress-bar-striped progress-bar-animated'
2314
+ };
2315
+ default:
2316
+ return {
2317
+ label: 'Queued',
2318
+ badgeClass: 'text-bg-secondary',
2319
+ progressClass: 'bg-secondary progress-bar-striped progress-bar-animated'
2320
+ };
2321
+ }
2322
+ }
2323
+ function formatUploadMessage(item) {
2324
+ if (item.status === 'failed' && item.error) {
2325
+ return item.error;
2326
+ }
2327
+ if (item.status === 'uploaded') {
2328
+ return 'Upload completed successfully.';
2329
+ }
2330
+ if (item.status === 'uploading') {
2331
+ return item.progress + '% uploaded';
2332
+ }
2333
+ return 'Waiting to upload...';
2334
+ }
2335
+ function renderUploadQueue() {
2336
+ uploadQueue.innerHTML = '';
2337
+ uploadItems.forEach(function (item) {
2338
+ var presentation = getUploadStatePresentation(item.status);
2339
+ var card = document.createElement('div');
2340
+ card.className = 'border rounded px-2 py-2 bg-white';
2341
+ var header = document.createElement('div');
2342
+ header.className = 'd-flex justify-content-between align-items-start gap-2';
2343
+ var fileDetails = document.createElement('div');
2344
+ fileDetails.className = 'flex-grow-1 min-w-0';
2345
+ fileDetails.appendChild(createTextElement('div', 'fw-semibold small', item.fileName));
2346
+ fileDetails.appendChild(createTextElement('div', 'text-muted small', formatFileSize(item.fileSize)));
2347
+ var badge = createTextElement('span', 'badge ' + presentation.badgeClass, presentation.label);
2348
+ header.appendChild(fileDetails);
2349
+ header.appendChild(badge);
2350
+ var progress = document.createElement('div');
2351
+ progress.className = 'progress mt-2';
2352
+ progress.setAttribute('role', 'progressbar');
2353
+ progress.setAttribute('aria-valuemin', '0');
2354
+ progress.setAttribute('aria-valuemax', '100');
2355
+ progress.setAttribute('aria-valuenow', item.progress.toString());
2356
+ var progressState = document.createElement('div');
2357
+ progressState.className = 'progress-bar ' + presentation.progressClass;
2358
+ progressState.style.width = item.progress + '%';
2359
+ progressState.textContent = item.progress + '%';
2360
+ progress.appendChild(progressState);
2361
+ var message = createTextElement('div', item.status === 'failed' ? 'small text-danger mt-2' : 'small text-muted mt-2', formatUploadMessage(item));
2362
+ card.appendChild(header);
2363
+ card.appendChild(progress);
2364
+ card.appendChild(message);
2365
+ uploadQueue.appendChild(card);
2366
+ });
2367
+ }
2368
+ function createUploadItem(file, index) {
2369
+ return {
2370
+ id: file.name + '::' + file.size + '::' + file.lastModified + '::' + index + '::' + Date.now(),
2371
+ fileName: file.name,
2372
+ fileSize: file.size,
2373
+ status: 'queued',
2374
+ progress: 0,
2375
+ error: null
2376
+ };
2377
+ }
2378
+ function updateUploadItem(itemId, updates) {
2379
+ uploadItems = uploadItems.map(function (item) {
2380
+ return item.id === itemId ? Object.assign({}, item, updates) : item;
2381
+ });
2382
+ renderUploadQueue();
2383
+ }
2384
+ function removeUploadItems(predicate) {
2385
+ uploadItems = uploadItems.filter(function (item) {
2386
+ return !predicate(item);
2387
+ });
2388
+ renderUploadQueue();
2389
+ }
2390
+ function uploadSingleDocument(file, itemIdToUpdate, fileIndex, totalFiles) {
2391
+ return new Promise(function (resolve, reject) {
2392
+ var formData = new FormData();
2393
+ formData.append('chatInteractionId', config.itemId);
2394
+ formData.append('files', file);
2395
+ var xhr = new XMLHttpRequest();
2396
+ xhr.open('POST', config.uploadDocumentUrl, true);
2397
+ xhr.upload.addEventListener('progress', function (event) {
2398
+ if (!event.lengthComputable) {
2399
+ return;
2400
+ }
2401
+ var fileProgress = Math.round(event.loaded / event.total * 100);
2402
+ updateUploadItem(itemIdToUpdate, {
2403
+ status: 'uploading',
2404
+ progress: fileProgress
2405
+ });
2406
+ var overallProgress = (fileIndex + event.loaded / event.total) / totalFiles * 100;
2407
+ showUploadProgress(overallProgress, 'Uploading ' + (fileIndex + 1) + ' of ' + totalFiles, 'progress-bar-striped progress-bar-animated');
2408
+ });
2409
+ xhr.addEventListener('load', function () {
2410
+ if (xhr.status >= 200 && xhr.status < 300) {
2411
+ try {
2412
+ resolve(JSON.parse(xhr.responseText));
2413
+ } catch (error) {
2414
+ reject(new Error('Upload failed: invalid server response.'));
2415
+ }
2416
+ return;
2417
+ }
2418
+ reject(new Error((xhr.responseText || 'Upload failed.').trim()));
2419
+ });
2420
+ xhr.addEventListener('error', function () {
2421
+ reject(new Error('Upload failed. Please check your connection and try again.'));
2422
+ });
2423
+ xhr.send(formData);
2424
+ });
2425
+ }
2426
+ function uploadDocuments(_x) {
2427
+ return _uploadDocuments.apply(this, arguments);
2428
+ }
2429
+ function _uploadDocuments() {
2430
+ _uploadDocuments = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(files) {
2431
+ var filesToUpload, duplicateItems, knownDocumentKeys, pendingItems, uploadedCount, failedUploads, i, file, pendingItem, result, uploaded, failed, missingUploadMessage, failedMessage, errorMessage, _t2, _t3;
2432
+ return _regenerator().w(function (_context6) {
2433
+ while (1) switch (_context6.p = _context6.n) {
2434
+ case 0:
2435
+ if (!(!config.uploadDocumentUrl || !files || files.length === 0)) {
2436
+ _context6.n = 1;
2437
+ break;
2438
+ }
2439
+ return _context6.a(2);
2440
+ case 1:
2441
+ if (!isUploadingDocuments) {
2442
+ _context6.n = 2;
2443
+ break;
2444
+ }
2445
+ showUploadStatus('A document upload is already in progress.', 'text-warning');
2446
+ return _context6.a(2);
2447
+ case 2:
2448
+ isUploadingDocuments = true;
2449
+ filesToUpload = [];
2450
+ duplicateItems = [];
2451
+ knownDocumentKeys = new Set(interactionDocuments.map(function (document) {
2452
+ return getDocumentKey(document.fileName, document.fileSize);
2453
+ }));
2454
+ Array.from(files).forEach(function (file) {
2455
+ if (isDuplicateFile(file, knownDocumentKeys)) {
2456
+ duplicateItems.push(file);
2457
+ return;
2458
+ }
2459
+ knownDocumentKeys.add(getDocumentKey(file.name, file.size));
2460
+ filesToUpload.push(file);
2461
+ });
2462
+ if (duplicateItems.length > 0) {
2463
+ uploadItems = uploadItems.concat(duplicateItems.map(function (file, index) {
2464
+ return Object.assign(createUploadItem(file, index), {
2465
+ status: 'failed',
2466
+ progress: 100,
2467
+ error: 'This document is already attached.'
2468
+ });
2469
+ }));
2470
+ renderUploadQueue();
2471
+ }
2472
+ if (!(filesToUpload.length === 0)) {
2473
+ _context6.n = 3;
2474
+ break;
2475
+ }
2476
+ isUploadingDocuments = false;
2477
+ showUploadStatus(duplicateItems.map(function (file) {
2478
+ return file.name + ': This document is already attached.';
2479
+ }).join(' | '), 'text-warning');
2480
+ showUploadProgress(null);
2481
+ return _context6.a(2);
2482
+ case 3:
2483
+ pendingItems = filesToUpload.map(createUploadItem);
2484
+ uploadItems = uploadItems.concat(pendingItems);
2485
+ renderUploadQueue();
2486
+ showUploadProgress(0, 'Preparing upload...', 'progress-bar-striped progress-bar-animated');
2487
+ fileInput.disabled = true;
2488
+ _context6.p = 4;
2489
+ uploadedCount = 0;
2490
+ failedUploads = duplicateItems.map(function (file) {
2491
+ return file.name + ': This document is already attached.';
2492
+ });
2493
+ i = 0;
2494
+ case 5:
2495
+ if (!(i < filesToUpload.length)) {
2496
+ _context6.n = 10;
2497
+ break;
2498
+ }
2499
+ file = filesToUpload[i];
2500
+ pendingItem = pendingItems[i];
2501
+ updateUploadItem(pendingItem.id, {
2502
+ status: 'uploading',
2503
+ progress: 0,
2504
+ error: null
2505
+ });
2506
+ showUploadStatus('Uploading ' + (i + 1) + ' of ' + filesToUpload.length + ' document(s)...', 'text-warning');
2507
+ _context6.p = 6;
2508
+ _context6.n = 7;
2509
+ return uploadSingleDocument(file, pendingItem.id, i, filesToUpload.length);
2510
+ case 7:
2511
+ result = _context6.v;
2512
+ uploaded = (Array.isArray(result.uploaded) ? result.uploaded : []).map(normalizeDocumentInfo).filter(function (document) {
2513
+ return document && document.documentId;
2514
+ });
2515
+ failed = Array.isArray(result.failed) ? result.failed : [];
2516
+ if (uploaded.length > 0) {
2517
+ uploadedCount += uploaded.length;
2518
+ interactionDocuments = interactionDocuments.concat(uploaded);
2519
+ updateUploadItem(pendingItem.id, {
2520
+ status: 'uploaded',
2521
+ progress: 100,
2522
+ error: null
2523
+ });
2524
+ } else {
2525
+ missingUploadMessage = failed.length > 0 ? failed.map(function (entry) {
2526
+ return entry.fileName + ': ' + entry.error;
2527
+ }).join(' | ') : 'The server did not confirm that the file was uploaded.';
2528
+ if (failed.length === 0) {
2529
+ failedUploads.push(missingUploadMessage);
2530
+ }
2531
+ updateUploadItem(pendingItem.id, {
2532
+ status: 'failed',
2533
+ progress: 100,
2534
+ error: missingUploadMessage
2535
+ });
2536
+ }
2537
+ if (failed.length > 0) {
2538
+ failedMessage = failed.map(function (entry) {
2539
+ return entry.fileName + ': ' + entry.error;
2540
+ }).join(' | ');
2541
+ failedUploads.push(failedMessage);
2542
+ updateUploadItem(pendingItem.id, {
2543
+ status: 'failed',
2544
+ progress: 100,
2545
+ error: failedMessage
2546
+ });
2547
+ }
2548
+ _context6.n = 9;
2549
+ break;
2550
+ case 8:
2551
+ _context6.p = 8;
2552
+ _t2 = _context6.v;
2553
+ errorMessage = _t2 && _t2.message ? _t2.message : 'Upload failed. Please try again.';
2554
+ console.error('Upload failed:', _t2);
2555
+ failedUploads.push(file.name + ': ' + errorMessage);
2556
+ updateUploadItem(pendingItem.id, {
2557
+ status: 'failed',
2558
+ progress: pendingItem.progress || 0,
2559
+ error: errorMessage
2560
+ });
2561
+ case 9:
2562
+ i++;
2563
+ _context6.n = 5;
2564
+ break;
2565
+ case 10:
2566
+ renderDocuments();
2567
+ if (!(failedUploads.length > 0)) {
2568
+ _context6.n = 11;
2569
+ break;
2570
+ }
2571
+ removeUploadItems(function (item) {
2572
+ return item.status === 'uploaded';
2573
+ });
2574
+ showUploadStatus((uploadedCount > 0 ? 'Uploaded ' + uploadedCount + ' document(s). ' : '') + failedUploads.join(' | '), uploadedCount > 0 ? 'text-warning' : 'text-danger');
2575
+ showUploadProgress(null);
2576
+ return _context6.a(2);
2577
+ case 11:
2578
+ removeUploadItems(function () {
2579
+ return true;
2580
+ });
2581
+ showUploadStatus('Uploaded ' + uploadedCount + ' document(s).', 'text-success');
2582
+ showUploadProgress(null);
2583
+ _context6.n = 13;
2584
+ break;
2585
+ case 12:
2586
+ _context6.p = 12;
2587
+ _t3 = _context6.v;
2588
+ console.error('Upload failed:', _t3);
2589
+ showUploadStatus('Upload failed. Please try again.', 'text-danger');
2590
+ showUploadProgress(null);
2591
+ case 13:
2592
+ _context6.p = 13;
2593
+ isUploadingDocuments = false;
2594
+ fileInput.disabled = false;
2595
+ fileInput.value = '';
2596
+ return _context6.f(13);
2597
+ case 14:
2598
+ return _context6.a(2);
2599
+ }
2600
+ }, _callee6, null, [[6, 8], [4, 12, 13, 14]]);
2601
+ }));
2602
+ return _uploadDocuments.apply(this, arguments);
2603
+ }
2604
+ function removeDocument(_x2) {
2605
+ return _removeDocument.apply(this, arguments);
2606
+ }
2607
+ function _removeDocument() {
2608
+ _removeDocument = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7(documentId) {
2609
+ var response, result, serverDocuments, _t4, _t5;
2610
+ return _regenerator().w(function (_context7) {
2611
+ while (1) switch (_context7.p = _context7.n) {
2612
+ case 0:
2613
+ if (!(!config.removeDocumentUrl || !documentId || !window.confirm('Remove this document?'))) {
2614
+ _context7.n = 1;
2615
+ break;
2616
+ }
2617
+ return _context7.a(2);
2618
+ case 1:
2619
+ _context7.p = 1;
2620
+ _context7.n = 2;
2621
+ return fetch(config.removeDocumentUrl, {
2622
+ method: 'POST',
2623
+ headers: {
2624
+ 'Content-Type': 'application/json'
2625
+ },
2626
+ body: JSON.stringify({
2627
+ itemId: config.itemId,
2628
+ documentId: documentId
2629
+ })
2630
+ });
2631
+ case 2:
2632
+ response = _context7.v;
2633
+ if (response.ok) {
2634
+ _context7.n = 4;
2635
+ break;
2636
+ }
2637
+ _t4 = console;
2638
+ _context7.n = 3;
2639
+ return response.text();
2640
+ case 3:
2641
+ _t4.error.call(_t4, 'Failed to remove document:', _context7.v);
2642
+ showUploadStatus('Failed to remove document.', 'text-danger');
2643
+ return _context7.a(2);
2644
+ case 4:
2645
+ _context7.n = 5;
2646
+ return response.json();
2647
+ case 5:
2648
+ result = _context7.v;
2649
+ serverDocuments = (Array.isArray(result.documents) ? result.documents : []).map(normalizeDocumentInfo).filter(function (document) {
2650
+ return document && document.documentId;
2651
+ });
2652
+ interactionDocuments = serverDocuments.length > 0 ? serverDocuments : interactionDocuments.filter(function (document) {
2653
+ return document.documentId !== documentId;
2654
+ });
2655
+ renderDocuments();
2656
+ showUploadStatus('Document removed.', 'text-success');
2657
+ _context7.n = 7;
2658
+ break;
2659
+ case 6:
2660
+ _context7.p = 6;
2661
+ _t5 = _context7.v;
2662
+ console.error('Remove failed:', _t5);
2663
+ showUploadStatus('Failed to remove document.', 'text-danger');
2664
+ case 7:
2665
+ return _context7.a(2);
2666
+ }
2667
+ }, _callee7, null, [[1, 6]]);
2668
+ }));
2669
+ return _removeDocument.apply(this, arguments);
2670
+ }
2671
+ var onFileInputChange = function onFileInputChange(event) {
2672
+ var selectedFiles = event.target.files ? Array.from(event.target.files) : [];
2673
+ uploadDocuments(selectedFiles);
2674
+ };
2675
+ fileInput.addEventListener('change', onFileInputChange);
2676
+ fileInput[managerStateKey] = {
2677
+ dispose: function dispose() {
2678
+ fileInput.removeEventListener('change', onFileInputChange);
2679
+ }
2680
+ };
2681
+ renderDocuments();
2682
+ renderUploadQueue();
2683
+ showUploadStatus(null);
2684
+ showUploadProgress(null);
2685
+ }
2686
+ return {
2687
+ initialize: initialize
2688
+ };
2689
+ }();
2135
2690
 
2136
2691
  // Download chart as image via event delegation (DOMPurify strips inline onclick).
2137
2692
  document.addEventListener('click', function (e) {