@crestapps/ai-chat-ui 1.0.0-rc.7 → 1.0.0
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 +158 -8
- package/dist/ai-chat-widget.js.map +1 -1
- package/dist/ai-chat-widget.min.js +1 -1
- package/dist/ai-chat-widget.min.js.map +1 -1
- package/dist/ai-chat.css +49 -17
- package/dist/ai-chat.css.map +1 -1
- package/dist/ai-chat.js +471 -169
- package/dist/ai-chat.js.map +1 -1
- package/dist/ai-chat.min.css +1 -1
- package/dist/ai-chat.min.js +1 -1
- package/dist/ai-chat.min.js.map +1 -1
- package/dist/chat-interaction-settings.js +63 -0
- package/dist/chat-interaction-settings.js.map +1 -1
- package/dist/chat-interaction-settings.min.js +1 -1
- package/dist/chat-interaction-settings.min.js.map +1 -1
- package/dist/chat-interaction.js +424 -163
- 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 +86 -35
- package/dist/chat-widget.css.map +1 -1
- package/dist/chat-widget.min.css +1 -1
- package/dist/document-drop-zone.css +10 -10
- package/dist/document-drop-zone.css.map +1 -1
- package/dist/document-drop-zone.js +92 -14
- package/dist/document-drop-zone.js.map +1 -1
- package/dist/document-drop-zone.min.css +1 -1
- package/dist/document-drop-zone.min.js +1 -1
- package/dist/document-drop-zone.min.js.map +1 -1
- package/package.json +1 -1
package/dist/ai-chat.js
CHANGED
|
@@ -22,7 +22,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
22
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
23
|
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
24
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); }
|
|
25
|
-
window.
|
|
25
|
+
window.coreAIChatManager = function () {
|
|
26
26
|
// Defaults (can be overridden by instanceConfig)
|
|
27
27
|
var defaultConfig = {
|
|
28
28
|
// UI defaults for generated media
|
|
@@ -36,7 +36,9 @@ window.openAIChatManager = function () {
|
|
|
36
36
|
thumbsUpTitle: 'Thumbs up',
|
|
37
37
|
thumbsDownTitle: 'Thumbs down',
|
|
38
38
|
copyTitle: 'Click here to copy response to clipboard.',
|
|
39
|
+
copiedTitle: 'Response copied to clipboard.',
|
|
39
40
|
codeCopiedText: 'Copied!',
|
|
41
|
+
copyResetDelayMs: 2000,
|
|
40
42
|
widget: {
|
|
41
43
|
chatWidgetContainer: null,
|
|
42
44
|
chatWidgetStateName: null,
|
|
@@ -55,8 +57,8 @@ window.openAIChatManager = function () {
|
|
|
55
57
|
minWidth: 320,
|
|
56
58
|
minHeight: 420
|
|
57
59
|
},
|
|
58
|
-
messageTemplate: "\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n
|
|
59
|
-
indicatorTemplate: "\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n
|
|
60
|
+
messageTemplate: "\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"'msg-' + index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-message-heading ai-chat-message-heading-user\">\n <span class=\"ai-chat-msg-role ai-chat-msg-role-user\">{{ userLabel }}</span>\n </div>\n <div v-else-if=\"message.role !== 'indicator'\" class=\"ai-chat-message-heading ai-chat-message-heading-assistant\">\n <div :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n <span class=\"ai-chat-message-role-label\">{{ getAssistantLabel(message) }}</span>\n </div>\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <ol v-if=\"message.citationReferences && message.citationReferences.length\" class=\"ai-chat-citation-list\">\n <li v-for=\"citation in message.citationReferences\" :key=\"'citation-' + (citation.referenceKey || citation.displayIndex)\" class=\"ai-chat-citation-item\">\n <a v-if=\"citation.link\" :href=\"citation.link\" :target=\"citation.isDownload ? null : '_blank'\" :rel=\"citation.isDownload ? null : 'noopener noreferrer'\">{{ citation.label }}</a>\n <span v-else>{{ citation.label }}</span>\n </li>\n </ol>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <template v-if=\"metricsEnabled && message.role === 'assistant'\">\n <span class=\"ai-chat-message-assistant-feedback\" :data-message-id=\"message.id\">\n <button type=\"button\" class=\"btn btn-sm btn-link text-success p-0 me-2 button-message-toolbox rate-up-btn\" @click=\"rateMessage(message, true, $event)\" :title=\"thumbsUpTitle\">\n <i class=\"fa-regular fa-thumbs-up\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-link text-danger p-0 me-2 button-message-toolbox rate-down-btn\" @click=\"rateMessage(message, false, $event)\" :title=\"thumbsDownTitle\">\n <i class=\"fa-regular fa-thumbs-down\"></i>\n </button>\n </span>\n </template>\n <button type=\"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 type=\"button\" class=\"btn btn-sm btn-link p-0 button-message-toolbox ai-response-copy-btn\" :class=\"copiedMessageIndex === index ? 'text-success' : 'text-secondary'\" :data-copy-message-index=\"index\" @click=\"copyResponse(message, index, $event)\" :title=\"copiedMessageIndex === index ? copiedTitle : copyTitle\">\n <i :class=\"copiedMessageIndex === index ? 'fa-solid fa-check' : '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 type=\"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 type=\"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 ",
|
|
61
|
+
indicatorTemplate: "\n <div class=\"ai-chat-message-heading ai-chat-message-heading-assistant\">\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 <span class=\"ai-chat-message-role-label\">Assistant</span>\n </div>\n </div>\n "
|
|
60
62
|
};
|
|
61
63
|
|
|
62
64
|
// Sanitize URLs to prevent javascript: protocol injection.
|
|
@@ -125,7 +127,7 @@ window.openAIChatManager = function () {
|
|
|
125
127
|
return Math.min(Math.max(value, min), max);
|
|
126
128
|
}
|
|
127
129
|
function normalizeReference(reference) {
|
|
128
|
-
var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$title, _ref4, _normalized$link, _ref5, _normalized$reference;
|
|
130
|
+
var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$title, _ref4, _normalized$link, _ref5, _normalized$reference, _normalized$isGenerat;
|
|
129
131
|
if (!reference || _typeof(reference) !== 'object') {
|
|
130
132
|
return null;
|
|
131
133
|
}
|
|
@@ -135,6 +137,7 @@ window.openAIChatManager = function () {
|
|
|
135
137
|
normalized.title = (_ref3 = (_normalized$title = normalized.title) !== null && _normalized$title !== void 0 ? _normalized$title : normalized.Title) !== null && _ref3 !== void 0 ? _ref3 : null;
|
|
136
138
|
normalized.link = sanitizeUrl((_ref4 = (_normalized$link = normalized.link) !== null && _normalized$link !== void 0 ? _normalized$link : normalized.Link) !== null && _ref4 !== void 0 ? _ref4 : null);
|
|
137
139
|
normalized.referenceType = (_ref5 = (_normalized$reference = normalized.referenceType) !== null && _normalized$reference !== void 0 ? _normalized$reference : normalized.ReferenceType) !== null && _ref5 !== void 0 ? _ref5 : null;
|
|
140
|
+
normalized.isGenerated = ((_normalized$isGenerat = normalized.isGenerated) !== null && _normalized$isGenerat !== void 0 ? _normalized$isGenerat : normalized.IsGenerated) === true;
|
|
138
141
|
return normalized;
|
|
139
142
|
}
|
|
140
143
|
function isDownloadCitationReference(reference) {
|
|
@@ -169,28 +172,42 @@ window.openAIChatManager = function () {
|
|
|
169
172
|
function buildCitationDisplay(content, references) {
|
|
170
173
|
var processedContent = (content || '').trim();
|
|
171
174
|
var messageReferences = normalizeReferences(references);
|
|
172
|
-
|
|
175
|
+
var referenceEntries = Object.entries(messageReferences);
|
|
176
|
+
if (!referenceEntries.length) {
|
|
173
177
|
return {
|
|
174
178
|
content: processedContent,
|
|
175
179
|
citations: []
|
|
176
180
|
};
|
|
177
181
|
}
|
|
178
|
-
var citedRefs =
|
|
182
|
+
var citedRefs = referenceEntries.filter(function (_ref6) {
|
|
179
183
|
var _ref7 = _slicedToArray(_ref6, 1),
|
|
180
184
|
key = _ref7[0];
|
|
181
185
|
return processedContent.includes(key);
|
|
182
186
|
});
|
|
183
|
-
|
|
187
|
+
var generatedRefs = referenceEntries.filter(function (_ref8) {
|
|
188
|
+
var _ref9 = _slicedToArray(_ref8, 2),
|
|
189
|
+
key = _ref9[0],
|
|
190
|
+
value = _ref9[1];
|
|
191
|
+
return value.isGenerated && !processedContent.includes(key);
|
|
192
|
+
});
|
|
193
|
+
if (!citedRefs.length && !generatedRefs.length) {
|
|
184
194
|
return {
|
|
185
195
|
content: processedContent,
|
|
186
196
|
citations: []
|
|
187
197
|
};
|
|
188
198
|
}
|
|
189
|
-
citedRefs.sort(function (
|
|
190
|
-
var
|
|
191
|
-
a =
|
|
192
|
-
var
|
|
193
|
-
b =
|
|
199
|
+
citedRefs.sort(function (_ref0, _ref1) {
|
|
200
|
+
var _ref10 = _slicedToArray(_ref0, 2),
|
|
201
|
+
a = _ref10[1];
|
|
202
|
+
var _ref11 = _slicedToArray(_ref1, 2),
|
|
203
|
+
b = _ref11[1];
|
|
204
|
+
return a.index - b.index;
|
|
205
|
+
});
|
|
206
|
+
generatedRefs.sort(function (_ref12, _ref13) {
|
|
207
|
+
var _ref14 = _slicedToArray(_ref12, 2),
|
|
208
|
+
a = _ref14[1];
|
|
209
|
+
var _ref15 = _slicedToArray(_ref13, 2),
|
|
210
|
+
b = _ref15[1];
|
|
194
211
|
return a.index - b.index;
|
|
195
212
|
});
|
|
196
213
|
var citations = [];
|
|
@@ -224,11 +241,36 @@ window.openAIChatManager = function () {
|
|
|
224
241
|
processedContent = processedContent.replaceAll(citation.placeholder, "<sup>".concat(citation.displayIndex, "</sup>"));
|
|
225
242
|
}
|
|
226
243
|
processedContent = processedContent.replaceAll('</sup><sup>', '</sup><sup>,</sup><sup>');
|
|
244
|
+
|
|
245
|
+
// Generated files (such as exported tabular data) are always offered as a download even when
|
|
246
|
+
// the model does not cite them inline, so the user never loses access to the produced file.
|
|
247
|
+
var _iterator2 = _createForOfIteratorHelper(generatedRefs),
|
|
248
|
+
_step2;
|
|
249
|
+
try {
|
|
250
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
251
|
+
var _step2$value = _slicedToArray(_step2.value, 2),
|
|
252
|
+
_key = _step2$value[0],
|
|
253
|
+
_value = _step2$value[1];
|
|
254
|
+
citations.push({
|
|
255
|
+
referenceKey: _key,
|
|
256
|
+
displayIndex: displayIndex,
|
|
257
|
+
label: getCitationLabel(_value, _key),
|
|
258
|
+
link: _value.link || null,
|
|
259
|
+
isDownload: true,
|
|
260
|
+
placeholder: null
|
|
261
|
+
});
|
|
262
|
+
displayIndex++;
|
|
263
|
+
}
|
|
264
|
+
} catch (err) {
|
|
265
|
+
_iterator2.e(err);
|
|
266
|
+
} finally {
|
|
267
|
+
_iterator2.f();
|
|
268
|
+
}
|
|
227
269
|
return {
|
|
228
270
|
content: processedContent,
|
|
229
|
-
citations: citations.map(function (
|
|
230
|
-
var placeholder =
|
|
231
|
-
citation = _objectWithoutProperties(
|
|
271
|
+
citations: citations.map(function (_ref16) {
|
|
272
|
+
var placeholder = _ref16.placeholder,
|
|
273
|
+
citation = _objectWithoutProperties(_ref16, _excluded);
|
|
232
274
|
return citation;
|
|
233
275
|
})
|
|
234
276
|
};
|
|
@@ -238,24 +280,24 @@ window.openAIChatManager = function () {
|
|
|
238
280
|
if (!copyContent || !Array.isArray(citations) || citations.length === 0) {
|
|
239
281
|
return copyContent;
|
|
240
282
|
}
|
|
241
|
-
var
|
|
242
|
-
|
|
283
|
+
var _iterator3 = _createForOfIteratorHelper(citations),
|
|
284
|
+
_step3;
|
|
243
285
|
try {
|
|
244
|
-
for (
|
|
245
|
-
var citation =
|
|
286
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
287
|
+
var citation = _step3.value;
|
|
246
288
|
copyContent = copyContent.replaceAll(citation.referenceKey, "[".concat(citation.displayIndex, "]"));
|
|
247
289
|
}
|
|
248
290
|
} catch (err) {
|
|
249
|
-
|
|
291
|
+
_iterator3.e(err);
|
|
250
292
|
} finally {
|
|
251
|
-
|
|
293
|
+
_iterator3.f();
|
|
252
294
|
}
|
|
253
295
|
copyContent += '\n\nReferences:\n';
|
|
254
|
-
var
|
|
255
|
-
|
|
296
|
+
var _iterator4 = _createForOfIteratorHelper(citations),
|
|
297
|
+
_step4;
|
|
256
298
|
try {
|
|
257
|
-
for (
|
|
258
|
-
var _citation =
|
|
299
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
300
|
+
var _citation = _step4.value;
|
|
259
301
|
copyContent += "".concat(_citation.displayIndex, ". ").concat(_citation.label);
|
|
260
302
|
if (_citation.link) {
|
|
261
303
|
copyContent += " - ".concat(_citation.link);
|
|
@@ -263,9 +305,9 @@ window.openAIChatManager = function () {
|
|
|
263
305
|
copyContent += '\n';
|
|
264
306
|
}
|
|
265
307
|
} catch (err) {
|
|
266
|
-
|
|
308
|
+
_iterator4.e(err);
|
|
267
309
|
} finally {
|
|
268
|
-
|
|
310
|
+
_iterator4.f();
|
|
269
311
|
}
|
|
270
312
|
return copyContent.trimEnd();
|
|
271
313
|
}
|
|
@@ -447,17 +489,17 @@ window.openAIChatManager = function () {
|
|
|
447
489
|
// Defer to requestAnimationFrame so the browser has fully laid out the
|
|
448
490
|
// canvas elements before Chart.js reads their dimensions.
|
|
449
491
|
requestAnimationFrame(function () {
|
|
450
|
-
var
|
|
451
|
-
|
|
492
|
+
var _iterator5 = _createForOfIteratorHelper(charts),
|
|
493
|
+
_step5;
|
|
452
494
|
try {
|
|
453
|
-
for (
|
|
454
|
-
var c =
|
|
495
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
496
|
+
var c = _step5.value;
|
|
455
497
|
renderChartOnCanvas(c.chartId, c.config);
|
|
456
498
|
}
|
|
457
499
|
} catch (err) {
|
|
458
|
-
|
|
500
|
+
_iterator5.e(err);
|
|
459
501
|
} finally {
|
|
460
|
-
|
|
502
|
+
_iterator5.f();
|
|
461
503
|
}
|
|
462
504
|
});
|
|
463
505
|
}
|
|
@@ -531,11 +573,31 @@ window.openAIChatManager = function () {
|
|
|
531
573
|
ADD_ATTR: ['target']
|
|
532
574
|
});
|
|
533
575
|
}
|
|
576
|
+
function compactObject(source) {
|
|
577
|
+
if (!source || _typeof(source) !== 'object') {
|
|
578
|
+
return {};
|
|
579
|
+
}
|
|
580
|
+
return Object.fromEntries(Object.entries(source).filter(function (_ref17) {
|
|
581
|
+
var _ref18 = _slicedToArray(_ref17, 2),
|
|
582
|
+
value = _ref18[1];
|
|
583
|
+
return value !== undefined;
|
|
584
|
+
}));
|
|
585
|
+
}
|
|
586
|
+
function resolveIndicatorTemplate(template, assistantLabel) {
|
|
587
|
+
if (!template) {
|
|
588
|
+
return template;
|
|
589
|
+
}
|
|
590
|
+
var encodedAssistantLabel = escapeHtmlEntities(assistantLabel || 'Assistant');
|
|
591
|
+
return template.replace(/\{\{\s*assistantLabel\s*\}\}/g, encodedAssistantLabel);
|
|
592
|
+
}
|
|
534
593
|
var initialize = function initialize(instanceConfig) {
|
|
535
|
-
var
|
|
536
|
-
|
|
537
|
-
var
|
|
538
|
-
|
|
594
|
+
var normalizedInstanceConfig = compactObject(instanceConfig);
|
|
595
|
+
var normalizedWidgetConfig = compactObject(normalizedInstanceConfig.widget);
|
|
596
|
+
var config = Object.assign({}, defaultConfig, normalizedInstanceConfig);
|
|
597
|
+
config.widget = Object.assign({}, defaultConfig.widget || {}, normalizedWidgetConfig);
|
|
598
|
+
config.indicatorTemplate = resolveIndicatorTemplate(config.indicatorTemplate, config.assistantLabel);
|
|
599
|
+
var hasWidgetConfig = !!(normalizedWidgetConfig.chatWidgetContainer && normalizedWidgetConfig.chatWidgetStateName);
|
|
600
|
+
var widgetBehavior = window.coreAIChatWidgetBehavior || null;
|
|
539
601
|
// Keep defaultConfig in sync so renderers use overridden values
|
|
540
602
|
defaultConfig = config;
|
|
541
603
|
if (!config.signalRHubUrl) {
|
|
@@ -587,6 +649,7 @@ window.openAIChatManager = function () {
|
|
|
587
649
|
thumbsUpTitle: config.thumbsUpTitle,
|
|
588
650
|
thumbsDownTitle: config.thumbsDownTitle,
|
|
589
651
|
copyTitle: config.copyTitle,
|
|
652
|
+
copiedTitle: config.copiedTitle,
|
|
590
653
|
isRecording: false,
|
|
591
654
|
mediaRecorder: null,
|
|
592
655
|
preRecordingPrompt: '',
|
|
@@ -611,7 +674,10 @@ window.openAIChatManager = function () {
|
|
|
611
674
|
pendingSessionPromise: null,
|
|
612
675
|
pendingSessionResolver: null,
|
|
613
676
|
pendingSessionRejector: null,
|
|
614
|
-
pendingSessionTimeoutId: null
|
|
677
|
+
pendingSessionTimeoutId: null,
|
|
678
|
+
copiedMessageIndex: -1,
|
|
679
|
+
copyResetTimeoutId: null,
|
|
680
|
+
activeCopyButton: null
|
|
615
681
|
};
|
|
616
682
|
},
|
|
617
683
|
computed: {
|
|
@@ -1120,10 +1186,12 @@ window.openAIChatManager = function () {
|
|
|
1120
1186
|
});
|
|
1121
1187
|
|
|
1122
1188
|
// When the session is new (no messages) and an initial prompt is configured,
|
|
1123
|
-
//
|
|
1189
|
+
// display it as the first assistant message without invoking the AI.
|
|
1124
1190
|
if (_this3.messages.length === 0 && config.initialPrompt) {
|
|
1125
|
-
_this3.
|
|
1126
|
-
|
|
1191
|
+
_this3.addMessage({
|
|
1192
|
+
role: 'assistant',
|
|
1193
|
+
content: config.initialPrompt
|
|
1194
|
+
});
|
|
1127
1195
|
}
|
|
1128
1196
|
});
|
|
1129
1197
|
_this3.connection.on("ReceiveError", function (error) {
|
|
@@ -1289,8 +1357,6 @@ window.openAIChatManager = function () {
|
|
|
1289
1357
|
console.info("SignalR: reconnected.");
|
|
1290
1358
|
if (_this3.isSessionStarted) {
|
|
1291
1359
|
_this3.reloadCurrentSession();
|
|
1292
|
-
} else if (config.autoCreateSession) {
|
|
1293
|
-
_this3.startNewSession();
|
|
1294
1360
|
}
|
|
1295
1361
|
});
|
|
1296
1362
|
_this3.connection.onclose(function (error) {
|
|
@@ -1325,14 +1391,14 @@ window.openAIChatManager = function () {
|
|
|
1325
1391
|
if (message.content && !message.htmlContent) {
|
|
1326
1392
|
message.htmlContent = parseMarkdownContent(message.content, message);
|
|
1327
1393
|
}
|
|
1328
|
-
this.fireEvent(new CustomEvent("
|
|
1394
|
+
this.fireEvent(new CustomEvent("addingCoreAIPromotMessage", {
|
|
1329
1395
|
detail: {
|
|
1330
1396
|
message: message
|
|
1331
1397
|
}
|
|
1332
1398
|
}));
|
|
1333
1399
|
this.messages.push(message);
|
|
1334
1400
|
this.$nextTick(function () {
|
|
1335
|
-
_this4.fireEvent(new CustomEvent("
|
|
1401
|
+
_this4.fireEvent(new CustomEvent("addedCoreAIPromotMessage", {
|
|
1336
1402
|
detail: {
|
|
1337
1403
|
message: message
|
|
1338
1404
|
}
|
|
@@ -1653,9 +1719,9 @@ window.openAIChatManager = function () {
|
|
|
1653
1719
|
var _this9 = this;
|
|
1654
1720
|
references = normalizeReferences(references);
|
|
1655
1721
|
if (Object.keys(references).length) {
|
|
1656
|
-
var
|
|
1722
|
+
var _ref23, _message$rawContent2;
|
|
1657
1723
|
var message = this.messages[messageIndex];
|
|
1658
|
-
message.rawContent = (
|
|
1724
|
+
message.rawContent = (_ref23 = (_message$rawContent2 = message.rawContent) !== null && _message$rawContent2 !== void 0 ? _message$rawContent2 : message.content) !== null && _ref23 !== void 0 ? _ref23 : '';
|
|
1659
1725
|
updateMessagePresentation(message, references);
|
|
1660
1726
|
this.messages[messageIndex] = message;
|
|
1661
1727
|
this.$nextTick(function () {
|
|
@@ -1723,8 +1789,38 @@ window.openAIChatManager = function () {
|
|
|
1723
1789
|
button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');
|
|
1724
1790
|
});
|
|
1725
1791
|
},
|
|
1726
|
-
|
|
1792
|
+
updateCopyButtons: function updateCopyButtons() {
|
|
1727
1793
|
var _this1 = this;
|
|
1794
|
+
if (!this.chatContainer) {
|
|
1795
|
+
return;
|
|
1796
|
+
}
|
|
1797
|
+
var buttons = this.chatContainer.querySelectorAll('[data-copy-message-index]');
|
|
1798
|
+
buttons.forEach(function (button) {
|
|
1799
|
+
var buttonIndex = Number(button.getAttribute('data-copy-message-index'));
|
|
1800
|
+
var isCopied = buttonIndex === _this1.copiedMessageIndex;
|
|
1801
|
+
var iconHtml = isCopied ? '<i class="fa-solid fa-check"></i>' : '<i class="fa-solid fa-copy"></i>';
|
|
1802
|
+
button.classList.toggle('text-success', isCopied);
|
|
1803
|
+
button.classList.toggle('text-secondary', !isCopied);
|
|
1804
|
+
button.setAttribute('title', isCopied ? _this1.copiedTitle : _this1.copyTitle);
|
|
1805
|
+
button.replaceChildren(DOMPurify.sanitize(iconHtml, {
|
|
1806
|
+
RETURN_DOM_FRAGMENT: true
|
|
1807
|
+
}));
|
|
1808
|
+
});
|
|
1809
|
+
},
|
|
1810
|
+
setCopyButtonState: function setCopyButtonState(button, isCopied) {
|
|
1811
|
+
if (!button) {
|
|
1812
|
+
return;
|
|
1813
|
+
}
|
|
1814
|
+
var iconHtml = isCopied ? '<i class="fa-solid fa-check"></i>' : '<i class="fa-solid fa-copy"></i>';
|
|
1815
|
+
button.classList.toggle('text-success', isCopied);
|
|
1816
|
+
button.classList.toggle('text-secondary', !isCopied);
|
|
1817
|
+
button.setAttribute('title', isCopied ? this.copiedTitle : this.copyTitle);
|
|
1818
|
+
button.replaceChildren(DOMPurify.sanitize(iconHtml, {
|
|
1819
|
+
RETURN_DOM_FRAGMENT: true
|
|
1820
|
+
}));
|
|
1821
|
+
},
|
|
1822
|
+
synthesizeSpeech: function synthesizeSpeech(text, cacheIndex) {
|
|
1823
|
+
var _this10 = this;
|
|
1728
1824
|
if (!this.textToSpeechEnabled || !text || !this.connection) {
|
|
1729
1825
|
return;
|
|
1730
1826
|
}
|
|
@@ -1733,16 +1829,16 @@ window.openAIChatManager = function () {
|
|
|
1733
1829
|
this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;
|
|
1734
1830
|
this.connection.invoke("SynthesizeSpeech", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)["catch"](function (err) {
|
|
1735
1831
|
console.error("TTS synthesis error:", err);
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
return
|
|
1832
|
+
_this10.isPlayingAudio = false;
|
|
1833
|
+
_this10.ttsPlayingMessageIndex = -1;
|
|
1834
|
+
_this10._ttsCacheIndex = -1;
|
|
1835
|
+
_this10.$nextTick(function () {
|
|
1836
|
+
return _this10.updateTtsPlaybackButtons();
|
|
1741
1837
|
});
|
|
1742
1838
|
});
|
|
1743
1839
|
},
|
|
1744
1840
|
toggleMessageTts: function toggleMessageTts(message, index) {
|
|
1745
|
-
var
|
|
1841
|
+
var _this11 = this;
|
|
1746
1842
|
if (this.ttsPlayingMessageIndex === index) {
|
|
1747
1843
|
this.stopAudio();
|
|
1748
1844
|
return;
|
|
@@ -1755,7 +1851,7 @@ window.openAIChatManager = function () {
|
|
|
1755
1851
|
}));
|
|
1756
1852
|
this.ttsPlayingMessageIndex = index;
|
|
1757
1853
|
this.$nextTick(function () {
|
|
1758
|
-
return
|
|
1854
|
+
return _this11.updateTtsPlaybackButtons();
|
|
1759
1855
|
});
|
|
1760
1856
|
if (this.ttsAudioCache[index]) {
|
|
1761
1857
|
this.playAudioBlob(this.ttsAudioCache[index]);
|
|
@@ -1764,13 +1860,13 @@ window.openAIChatManager = function () {
|
|
|
1764
1860
|
this.synthesizeSpeech(message.content, index);
|
|
1765
1861
|
},
|
|
1766
1862
|
playCollectedAudio: function playCollectedAudio() {
|
|
1767
|
-
var
|
|
1863
|
+
var _this12 = this;
|
|
1768
1864
|
if (this.audioChunks.length === 0) {
|
|
1769
1865
|
if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {
|
|
1770
1866
|
this.isPlayingAudio = false;
|
|
1771
1867
|
this.ttsPlayingMessageIndex = -1;
|
|
1772
1868
|
this.$nextTick(function () {
|
|
1773
|
-
return
|
|
1869
|
+
return _this12.updateTtsPlaybackButtons();
|
|
1774
1870
|
});
|
|
1775
1871
|
}
|
|
1776
1872
|
return;
|
|
@@ -1780,18 +1876,18 @@ window.openAIChatManager = function () {
|
|
|
1780
1876
|
}, 0);
|
|
1781
1877
|
var combined = new Uint8Array(totalLength);
|
|
1782
1878
|
var offset = 0;
|
|
1783
|
-
var
|
|
1784
|
-
|
|
1879
|
+
var _iterator6 = _createForOfIteratorHelper(this.audioChunks),
|
|
1880
|
+
_step6;
|
|
1785
1881
|
try {
|
|
1786
|
-
for (
|
|
1787
|
-
var chunk =
|
|
1882
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
1883
|
+
var chunk = _step6.value;
|
|
1788
1884
|
combined.set(chunk, offset);
|
|
1789
1885
|
offset += chunk.length;
|
|
1790
1886
|
}
|
|
1791
1887
|
} catch (err) {
|
|
1792
|
-
|
|
1888
|
+
_iterator6.e(err);
|
|
1793
1889
|
} finally {
|
|
1794
|
-
|
|
1890
|
+
_iterator6.f();
|
|
1795
1891
|
}
|
|
1796
1892
|
this.audioChunks = [];
|
|
1797
1893
|
var blob = new Blob([combined], {
|
|
@@ -1810,39 +1906,39 @@ window.openAIChatManager = function () {
|
|
|
1810
1906
|
this.playAudioBlob(blob);
|
|
1811
1907
|
},
|
|
1812
1908
|
playAudioBlob: function playAudioBlob(blob) {
|
|
1813
|
-
var
|
|
1909
|
+
var _this13 = this;
|
|
1814
1910
|
var url = URL.createObjectURL(blob);
|
|
1815
1911
|
var audio = new Audio(url);
|
|
1816
1912
|
this.currentAudioUrl = url;
|
|
1817
1913
|
this.currentAudioElement = audio;
|
|
1818
1914
|
this.isPlayingAudio = true;
|
|
1819
1915
|
audio.addEventListener('ended', function () {
|
|
1820
|
-
|
|
1821
|
-
|
|
1916
|
+
_this13.currentAudioElement = null;
|
|
1917
|
+
_this13.currentAudioUrl = null;
|
|
1822
1918
|
URL.revokeObjectURL(url);
|
|
1823
|
-
|
|
1919
|
+
_this13.playNextInQueue();
|
|
1824
1920
|
});
|
|
1825
1921
|
audio.addEventListener('error', function () {
|
|
1826
|
-
|
|
1827
|
-
|
|
1922
|
+
_this13.currentAudioElement = null;
|
|
1923
|
+
_this13.currentAudioUrl = null;
|
|
1828
1924
|
URL.revokeObjectURL(url);
|
|
1829
|
-
|
|
1925
|
+
_this13.playNextInQueue();
|
|
1830
1926
|
});
|
|
1831
1927
|
audio.play()["catch"](function (err) {
|
|
1832
1928
|
console.error("Audio playback error:", err);
|
|
1833
|
-
|
|
1834
|
-
|
|
1929
|
+
_this13.currentAudioElement = null;
|
|
1930
|
+
_this13.currentAudioUrl = null;
|
|
1835
1931
|
URL.revokeObjectURL(url);
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
return
|
|
1932
|
+
_this13.audioPlayQueue = [];
|
|
1933
|
+
_this13.isPlayingAudio = false;
|
|
1934
|
+
_this13.ttsPlayingMessageIndex = -1;
|
|
1935
|
+
_this13.$nextTick(function () {
|
|
1936
|
+
return _this13.updateTtsPlaybackButtons();
|
|
1841
1937
|
});
|
|
1842
1938
|
});
|
|
1843
1939
|
},
|
|
1844
1940
|
playNextInQueue: function playNextInQueue() {
|
|
1845
|
-
var
|
|
1941
|
+
var _this14 = this;
|
|
1846
1942
|
if (this.audioPlayQueue.length > 0) {
|
|
1847
1943
|
var nextBlob = this.audioPlayQueue.shift();
|
|
1848
1944
|
this.playAudioBlob(nextBlob);
|
|
@@ -1850,13 +1946,13 @@ window.openAIChatManager = function () {
|
|
|
1850
1946
|
this.isPlayingAudio = false;
|
|
1851
1947
|
this.ttsPlayingMessageIndex = -1;
|
|
1852
1948
|
this.$nextTick(function () {
|
|
1853
|
-
return
|
|
1949
|
+
return _this14.updateTtsPlaybackButtons();
|
|
1854
1950
|
});
|
|
1855
1951
|
this.conversationModeOnAudioEnded();
|
|
1856
1952
|
}
|
|
1857
1953
|
},
|
|
1858
1954
|
stopAudio: function stopAudio() {
|
|
1859
|
-
var
|
|
1955
|
+
var _this15 = this;
|
|
1860
1956
|
if (this.currentAudioElement) {
|
|
1861
1957
|
this.currentAudioElement.pause();
|
|
1862
1958
|
this.currentAudioElement.currentTime = 0;
|
|
@@ -1871,7 +1967,7 @@ window.openAIChatManager = function () {
|
|
|
1871
1967
|
this.isPlayingAudio = false;
|
|
1872
1968
|
this.ttsPlayingMessageIndex = -1;
|
|
1873
1969
|
this.$nextTick(function () {
|
|
1874
|
-
return
|
|
1970
|
+
return _this15.updateTtsPlaybackButtons();
|
|
1875
1971
|
});
|
|
1876
1972
|
},
|
|
1877
1973
|
toggleConversationMode: function toggleConversationMode() {
|
|
@@ -1882,7 +1978,7 @@ window.openAIChatManager = function () {
|
|
|
1882
1978
|
}
|
|
1883
1979
|
},
|
|
1884
1980
|
startConversationMode: function startConversationMode() {
|
|
1885
|
-
var
|
|
1981
|
+
var _this16 = this;
|
|
1886
1982
|
if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {
|
|
1887
1983
|
return;
|
|
1888
1984
|
}
|
|
@@ -1902,12 +1998,12 @@ window.openAIChatManager = function () {
|
|
|
1902
1998
|
}
|
|
1903
1999
|
}).then(function (stream) {
|
|
1904
2000
|
var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus') ? 'audio/ogg;codecs=opus' : MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
|
|
1905
|
-
|
|
2001
|
+
_this16.mediaRecorder = new MediaRecorder(stream, {
|
|
1906
2002
|
mimeType: mimeType,
|
|
1907
2003
|
audioBitsPerSecond: 128000
|
|
1908
2004
|
});
|
|
1909
|
-
|
|
1910
|
-
|
|
2005
|
+
_this16._conversationSubject = new signalR.Subject();
|
|
2006
|
+
_this16._conversationStream = stream;
|
|
1911
2007
|
|
|
1912
2008
|
// Create an AnalyserNode for volume-based interrupt detection.
|
|
1913
2009
|
// During TTS playback, detect when the user speaks above
|
|
@@ -1916,20 +2012,20 @@ window.openAIChatManager = function () {
|
|
|
1916
2012
|
// speaker echo so the STT stream has no gaps.
|
|
1917
2013
|
var AudioCtx = window.AudioContext || window.webkitAudioContext;
|
|
1918
2014
|
if (AudioCtx) {
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
var micSource =
|
|
1923
|
-
micSource.connect(
|
|
2015
|
+
_this16._conversationAudioCtx = new AudioCtx();
|
|
2016
|
+
_this16._conversationAnalyser = _this16._conversationAudioCtx.createAnalyser();
|
|
2017
|
+
_this16._conversationAnalyser.fftSize = 256;
|
|
2018
|
+
var micSource = _this16._conversationAudioCtx.createMediaStreamSource(stream);
|
|
2019
|
+
micSource.connect(_this16._conversationAnalyser);
|
|
1924
2020
|
}
|
|
1925
2021
|
var pendingChunk = Promise.resolve();
|
|
1926
|
-
var analyser =
|
|
2022
|
+
var analyser = _this16._conversationAnalyser;
|
|
1927
2023
|
var interruptVolumeThreshold = 30;
|
|
1928
|
-
|
|
2024
|
+
_this16.mediaRecorder.addEventListener('dataavailable', function (e) {
|
|
1929
2025
|
if (e.data && e.data.size > 0) {
|
|
1930
2026
|
// During TTS playback, check mic volume to detect
|
|
1931
2027
|
// user interruption (speaking above threshold).
|
|
1932
|
-
if (
|
|
2028
|
+
if (_this16.isPlayingAudio && analyser) {
|
|
1933
2029
|
var freqData = new Uint8Array(analyser.frequencyBinCount);
|
|
1934
2030
|
analyser.getByteFrequencyData(freqData);
|
|
1935
2031
|
var sum = 0;
|
|
@@ -1939,7 +2035,7 @@ window.openAIChatManager = function () {
|
|
|
1939
2035
|
var avg = sum / freqData.length;
|
|
1940
2036
|
if (avg >= interruptVolumeThreshold) {
|
|
1941
2037
|
// User is speaking — interrupt TTS playback.
|
|
1942
|
-
|
|
2038
|
+
_this16.stopAudio();
|
|
1943
2039
|
}
|
|
1944
2040
|
}
|
|
1945
2041
|
|
|
@@ -1961,7 +2057,7 @@ window.openAIChatManager = function () {
|
|
|
1961
2057
|
}, '');
|
|
1962
2058
|
base64 = btoa(binaryString);
|
|
1963
2059
|
try {
|
|
1964
|
-
|
|
2060
|
+
_this16._conversationSubject.next(base64);
|
|
1965
2061
|
} catch (err) {
|
|
1966
2062
|
// Subject may have been completed already.
|
|
1967
2063
|
}
|
|
@@ -1972,28 +2068,28 @@ window.openAIChatManager = function () {
|
|
|
1972
2068
|
})));
|
|
1973
2069
|
}
|
|
1974
2070
|
});
|
|
1975
|
-
|
|
2071
|
+
_this16.mediaRecorder.addEventListener('stop', function () {
|
|
1976
2072
|
stream.getTracks().forEach(function (track) {
|
|
1977
2073
|
return track.stop();
|
|
1978
2074
|
});
|
|
1979
2075
|
pendingChunk.then(function () {
|
|
1980
2076
|
try {
|
|
1981
|
-
|
|
2077
|
+
_this16._conversationSubject.complete();
|
|
1982
2078
|
} catch (err) {
|
|
1983
2079
|
// Already completed.
|
|
1984
2080
|
}
|
|
1985
2081
|
});
|
|
1986
2082
|
});
|
|
1987
|
-
var profileId =
|
|
1988
|
-
var sessionId =
|
|
2083
|
+
var profileId = _this16.getProfileId();
|
|
2084
|
+
var sessionId = _this16.getSessionId() || '';
|
|
1989
2085
|
var language = navigator.language || document.documentElement.lang || 'en-US';
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
2086
|
+
_this16.connection.send("StartConversation", profileId, sessionId, _this16._conversationSubject, mimeType, language);
|
|
2087
|
+
_this16.mediaRecorder.start(250);
|
|
2088
|
+
_this16.isRecording = true;
|
|
1993
2089
|
})["catch"](function (err) {
|
|
1994
2090
|
console.error('Microphone access denied:', err);
|
|
1995
|
-
|
|
1996
|
-
|
|
2091
|
+
_this16.isConversationMode = false;
|
|
2092
|
+
_this16.updateConversationButton();
|
|
1997
2093
|
});
|
|
1998
2094
|
},
|
|
1999
2095
|
stopConversationMode: function stopConversationMode() {
|
|
@@ -2120,7 +2216,7 @@ window.openAIChatManager = function () {
|
|
|
2120
2216
|
return removedCount;
|
|
2121
2217
|
},
|
|
2122
2218
|
receiveNotification: function receiveNotification(notification) {
|
|
2123
|
-
var
|
|
2219
|
+
var _this17 = this;
|
|
2124
2220
|
if (!notification || !notification.type) {
|
|
2125
2221
|
return;
|
|
2126
2222
|
}
|
|
@@ -2135,7 +2231,7 @@ window.openAIChatManager = function () {
|
|
|
2135
2231
|
}
|
|
2136
2232
|
this.scheduleNotificationDismiss(notification);
|
|
2137
2233
|
this.$nextTick(function () {
|
|
2138
|
-
|
|
2234
|
+
_this17.scrollToBottom();
|
|
2139
2235
|
});
|
|
2140
2236
|
},
|
|
2141
2237
|
updateNotification: function updateNotification(notification) {
|
|
@@ -2152,12 +2248,12 @@ window.openAIChatManager = function () {
|
|
|
2152
2248
|
}
|
|
2153
2249
|
},
|
|
2154
2250
|
scheduleNotificationDismiss: function scheduleNotificationDismiss(notification) {
|
|
2155
|
-
var
|
|
2251
|
+
var _this18 = this;
|
|
2156
2252
|
if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {
|
|
2157
2253
|
return;
|
|
2158
2254
|
}
|
|
2159
2255
|
this.notificationDismissTimers[notification.type] = setTimeout(function () {
|
|
2160
|
-
|
|
2256
|
+
_this18.removeNotification(notification.type);
|
|
2161
2257
|
}, notification.autoDismissMs);
|
|
2162
2258
|
},
|
|
2163
2259
|
clearNotificationDismiss: function clearNotificationDismiss(notificationType) {
|
|
@@ -2187,12 +2283,12 @@ window.openAIChatManager = function () {
|
|
|
2187
2283
|
});
|
|
2188
2284
|
},
|
|
2189
2285
|
scrollToBottom: function scrollToBottom() {
|
|
2190
|
-
var
|
|
2286
|
+
var _this19 = this;
|
|
2191
2287
|
if (!this.autoScroll) {
|
|
2192
2288
|
return;
|
|
2193
2289
|
}
|
|
2194
2290
|
setTimeout(function () {
|
|
2195
|
-
|
|
2291
|
+
_this19.chatContainer.scrollTop = _this19.chatContainer.scrollHeight - _this19.chatContainer.clientHeight;
|
|
2196
2292
|
}, 50);
|
|
2197
2293
|
},
|
|
2198
2294
|
handleUserInput: function handleUserInput(event) {
|
|
@@ -2215,12 +2311,17 @@ window.openAIChatManager = function () {
|
|
|
2215
2311
|
this.sessionRating = null;
|
|
2216
2312
|
this.messages = [];
|
|
2217
2313
|
this.documents = [];
|
|
2218
|
-
|
|
2314
|
+
|
|
2315
|
+
// When an initial prompt is configured, show it as the first
|
|
2316
|
+
// assistant message instead of the generic placeholder.
|
|
2317
|
+
if (config.initialPrompt) {
|
|
2318
|
+
this.addMessage({
|
|
2319
|
+
role: 'assistant',
|
|
2320
|
+
content: config.initialPrompt
|
|
2321
|
+
});
|
|
2322
|
+
} else {
|
|
2219
2323
|
this.showPlaceholder();
|
|
2220
2324
|
}
|
|
2221
|
-
if (config.autoCreateSession) {
|
|
2222
|
-
this.startNewSession();
|
|
2223
|
-
}
|
|
2224
2325
|
if (widgetBehavior && typeof widgetBehavior.onSessionReset === 'function') {
|
|
2225
2326
|
widgetBehavior.onSessionReset(this, config);
|
|
2226
2327
|
}
|
|
@@ -2238,27 +2339,27 @@ window.openAIChatManager = function () {
|
|
|
2238
2339
|
});
|
|
2239
2340
|
},
|
|
2240
2341
|
ensureSessionForDocuments: function ensureSessionForDocuments(profileId) {
|
|
2241
|
-
var
|
|
2342
|
+
var _this20 = this;
|
|
2242
2343
|
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9() {
|
|
2243
2344
|
var sessionId;
|
|
2244
2345
|
return _regenerator().w(function (_context9) {
|
|
2245
2346
|
while (1) switch (_context9.n) {
|
|
2246
2347
|
case 0:
|
|
2247
|
-
sessionId =
|
|
2348
|
+
sessionId = _this20.getSessionId();
|
|
2248
2349
|
if (!sessionId) {
|
|
2249
2350
|
_context9.n = 1;
|
|
2250
2351
|
break;
|
|
2251
2352
|
}
|
|
2252
2353
|
return _context9.a(2, sessionId);
|
|
2253
2354
|
case 1:
|
|
2254
|
-
if (!(!profileId || !
|
|
2355
|
+
if (!(!profileId || !_this20.connection)) {
|
|
2255
2356
|
_context9.n = 2;
|
|
2256
2357
|
break;
|
|
2257
2358
|
}
|
|
2258
2359
|
return _context9.a(2, null);
|
|
2259
2360
|
case 2:
|
|
2260
2361
|
_context9.n = 3;
|
|
2261
|
-
return
|
|
2362
|
+
return _this20.requestNewSession(profileId);
|
|
2262
2363
|
case 3:
|
|
2263
2364
|
return _context9.a(2, _context9.v);
|
|
2264
2365
|
}
|
|
@@ -2266,7 +2367,7 @@ window.openAIChatManager = function () {
|
|
|
2266
2367
|
}))();
|
|
2267
2368
|
},
|
|
2268
2369
|
requestNewSession: function requestNewSession(profileId) {
|
|
2269
|
-
var
|
|
2370
|
+
var _this21 = this;
|
|
2270
2371
|
if (this.pendingSessionPromise) {
|
|
2271
2372
|
return this.pendingSessionPromise;
|
|
2272
2373
|
}
|
|
@@ -2274,14 +2375,14 @@ window.openAIChatManager = function () {
|
|
|
2274
2375
|
return Promise.resolve(null);
|
|
2275
2376
|
}
|
|
2276
2377
|
this.pendingSessionPromise = new Promise(function (resolve, reject) {
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2378
|
+
_this21.pendingSessionResolver = resolve;
|
|
2379
|
+
_this21.pendingSessionRejector = reject;
|
|
2380
|
+
_this21.pendingSessionTimeoutId = window.setTimeout(function () {
|
|
2381
|
+
_this21.rejectPendingSessionRequest('Timed out while creating a chat session.');
|
|
2281
2382
|
}, 15000);
|
|
2282
2383
|
});
|
|
2283
2384
|
this.connection.invoke("StartSession", profileId, null)["catch"](function (err) {
|
|
2284
|
-
|
|
2385
|
+
_this21.rejectPendingSessionRequest(err);
|
|
2285
2386
|
});
|
|
2286
2387
|
return this.pendingSessionPromise;
|
|
2287
2388
|
},
|
|
@@ -2307,7 +2408,7 @@ window.openAIChatManager = function () {
|
|
|
2307
2408
|
this.pendingSessionTimeoutId = null;
|
|
2308
2409
|
},
|
|
2309
2410
|
initializeApp: function initializeApp() {
|
|
2310
|
-
var
|
|
2411
|
+
var _this22 = this;
|
|
2311
2412
|
this.inputElement = document.querySelector(config.inputElementSelector);
|
|
2312
2413
|
this.buttonElement = document.querySelector(config.sendButtonElementSelector);
|
|
2313
2414
|
this.chatContainer = document.querySelector(config.chatContainerElementSelector);
|
|
@@ -2325,8 +2426,6 @@ window.openAIChatManager = function () {
|
|
|
2325
2426
|
var sessionId = this.getSessionId();
|
|
2326
2427
|
if (!hasWidgetConfig && sessionId) {
|
|
2327
2428
|
this.loadSession(sessionId);
|
|
2328
|
-
} else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {
|
|
2329
|
-
this.startNewSession();
|
|
2330
2429
|
}
|
|
2331
2430
|
|
|
2332
2431
|
// Initialize document bar if enabled.
|
|
@@ -2345,7 +2444,7 @@ window.openAIChatManager = function () {
|
|
|
2345
2444
|
fileInput.accept = config.allowedExtensions;
|
|
2346
2445
|
}
|
|
2347
2446
|
fileInput.addEventListener('change', function (e) {
|
|
2348
|
-
return
|
|
2447
|
+
return _this22.handleFileInputChange(e);
|
|
2349
2448
|
});
|
|
2350
2449
|
this.documentBar.parentElement.appendChild(fileInput);
|
|
2351
2450
|
|
|
@@ -2353,13 +2452,13 @@ window.openAIChatManager = function () {
|
|
|
2353
2452
|
var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;
|
|
2354
2453
|
if (inputArea) {
|
|
2355
2454
|
inputArea.addEventListener('dragover', function (e) {
|
|
2356
|
-
return
|
|
2455
|
+
return _this22.handleDragOver(e);
|
|
2357
2456
|
});
|
|
2358
2457
|
inputArea.addEventListener('dragleave', function (e) {
|
|
2359
|
-
return
|
|
2458
|
+
return _this22.handleDragLeave(e);
|
|
2360
2459
|
});
|
|
2361
2460
|
inputArea.addEventListener('drop', function (e) {
|
|
2362
|
-
return
|
|
2461
|
+
return _this22.handleDrop(e);
|
|
2363
2462
|
});
|
|
2364
2463
|
}
|
|
2365
2464
|
}
|
|
@@ -2367,55 +2466,55 @@ window.openAIChatManager = function () {
|
|
|
2367
2466
|
|
|
2368
2467
|
// Pause auto-scroll when the user manually scrolls up during streaming.
|
|
2369
2468
|
this.chatContainer.addEventListener('scroll', function () {
|
|
2370
|
-
if (!
|
|
2469
|
+
if (!_this22.stream) {
|
|
2371
2470
|
return;
|
|
2372
2471
|
}
|
|
2373
2472
|
var threshold = 30;
|
|
2374
|
-
var atBottom =
|
|
2375
|
-
|
|
2473
|
+
var atBottom = _this22.chatContainer.scrollHeight - _this22.chatContainer.clientHeight - _this22.chatContainer.scrollTop <= threshold;
|
|
2474
|
+
_this22.autoScroll = atBottom;
|
|
2376
2475
|
});
|
|
2377
2476
|
this.inputElement.addEventListener('keydown', function (event) {
|
|
2378
|
-
if (
|
|
2477
|
+
if (_this22.stream != null) {
|
|
2379
2478
|
return;
|
|
2380
2479
|
}
|
|
2381
2480
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
2382
2481
|
event.preventDefault();
|
|
2383
|
-
|
|
2482
|
+
_this22.buttonElement.click();
|
|
2384
2483
|
}
|
|
2385
2484
|
});
|
|
2386
2485
|
this.inputElement.addEventListener('input', function (e) {
|
|
2387
|
-
|
|
2486
|
+
_this22.handleUserInput(e);
|
|
2388
2487
|
if (e.target.value.trim()) {
|
|
2389
|
-
|
|
2488
|
+
_this22.buttonElement.removeAttribute('disabled');
|
|
2390
2489
|
} else {
|
|
2391
|
-
|
|
2490
|
+
_this22.buttonElement.setAttribute('disabled', true);
|
|
2392
2491
|
}
|
|
2393
2492
|
});
|
|
2394
2493
|
this.buttonElement.addEventListener('click', function () {
|
|
2395
|
-
if (
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2494
|
+
if (_this22.stream != null) {
|
|
2495
|
+
_this22.stream.dispose();
|
|
2496
|
+
_this22.stream = null;
|
|
2497
|
+
_this22.streamingFinished();
|
|
2498
|
+
_this22.hideTypingIndicator();
|
|
2400
2499
|
|
|
2401
2500
|
// Clean up: remove empty assistant message or stop streaming animation.
|
|
2402
|
-
if (
|
|
2403
|
-
var lastMsg =
|
|
2501
|
+
if (_this22.messages.length > 0) {
|
|
2502
|
+
var lastMsg = _this22.messages[_this22.messages.length - 1];
|
|
2404
2503
|
if (lastMsg.role === 'assistant' && !lastMsg.content) {
|
|
2405
|
-
|
|
2504
|
+
_this22.messages.pop();
|
|
2406
2505
|
} else if (lastMsg.isStreaming) {
|
|
2407
2506
|
lastMsg.isStreaming = false;
|
|
2408
2507
|
}
|
|
2409
2508
|
}
|
|
2410
2509
|
return;
|
|
2411
2510
|
}
|
|
2412
|
-
|
|
2511
|
+
_this22.sendMessage();
|
|
2413
2512
|
});
|
|
2414
2513
|
var promptGenerators = document.getElementsByClassName('profile-generated-prompt');
|
|
2415
2514
|
for (var i = 0; i < promptGenerators.length; i++) {
|
|
2416
2515
|
promptGenerators[i].addEventListener('click', function (e) {
|
|
2417
2516
|
e.preventDefault();
|
|
2418
|
-
|
|
2517
|
+
_this22.generatePrompt(e.target);
|
|
2419
2518
|
});
|
|
2420
2519
|
}
|
|
2421
2520
|
var chatSessions = document.getElementsByClassName('chat-session-history-item');
|
|
@@ -2427,17 +2526,27 @@ window.openAIChatManager = function () {
|
|
|
2427
2526
|
console.error('an element with the class chat-session-history-item with no data-session-id set.');
|
|
2428
2527
|
return;
|
|
2429
2528
|
}
|
|
2430
|
-
|
|
2431
|
-
|
|
2529
|
+
_this22.loadSession(sessionId);
|
|
2530
|
+
_this22.showChatScreen();
|
|
2432
2531
|
});
|
|
2433
2532
|
}
|
|
2434
|
-
|
|
2435
|
-
|
|
2533
|
+
var initialMessages = Array.isArray(config.messages) ? config.messages : [];
|
|
2534
|
+
for (var _i5 = 0; _i5 < initialMessages.length; _i5++) {
|
|
2535
|
+
this.addMessage(initialMessages[_i5]);
|
|
2536
|
+
}
|
|
2537
|
+
|
|
2538
|
+
// When no messages were loaded and an initial prompt is configured,
|
|
2539
|
+
// display it as the first assistant message without invoking the AI.
|
|
2540
|
+
if (this.messages.length === 0 && config.initialPrompt) {
|
|
2541
|
+
this.addMessage({
|
|
2542
|
+
role: 'assistant',
|
|
2543
|
+
content: config.initialPrompt
|
|
2544
|
+
});
|
|
2436
2545
|
}
|
|
2437
2546
|
|
|
2438
2547
|
// Update feedback icons in the DOM after initial messages have rendered.
|
|
2439
2548
|
this.$nextTick(function () {
|
|
2440
|
-
|
|
2549
|
+
_this22.refreshAllFeedbackIcons();
|
|
2441
2550
|
});
|
|
2442
2551
|
|
|
2443
2552
|
// Delegate click for code block copy buttons.
|
|
@@ -2469,7 +2578,7 @@ window.openAIChatManager = function () {
|
|
|
2469
2578
|
if (this.micButton) {
|
|
2470
2579
|
this.micButton.style.display = '';
|
|
2471
2580
|
this.micButton.addEventListener('click', function () {
|
|
2472
|
-
|
|
2581
|
+
_this22.toggleRecording();
|
|
2473
2582
|
});
|
|
2474
2583
|
}
|
|
2475
2584
|
}
|
|
@@ -2479,7 +2588,7 @@ window.openAIChatManager = function () {
|
|
|
2479
2588
|
this.conversationButton = document.querySelector(config.conversationButtonElementSelector);
|
|
2480
2589
|
if (this.conversationButton) {
|
|
2481
2590
|
this.conversationButton.addEventListener('click', function () {
|
|
2482
|
-
|
|
2591
|
+
_this22.toggleConversationMode();
|
|
2483
2592
|
});
|
|
2484
2593
|
}
|
|
2485
2594
|
}
|
|
@@ -2503,7 +2612,7 @@ window.openAIChatManager = function () {
|
|
|
2503
2612
|
}
|
|
2504
2613
|
return;
|
|
2505
2614
|
}
|
|
2506
|
-
this.fireEvent(new CustomEvent("
|
|
2615
|
+
this.fireEvent(new CustomEvent("initializingSessionCoreAIChat", {
|
|
2507
2616
|
detail: {
|
|
2508
2617
|
sessionId: sessionId
|
|
2509
2618
|
}
|
|
@@ -2514,6 +2623,13 @@ window.openAIChatManager = function () {
|
|
|
2514
2623
|
if (widgetBehavior && typeof widgetBehavior.onSessionInitialized === 'function') {
|
|
2515
2624
|
widgetBehavior.onSessionInitialized(this, sessionId, config);
|
|
2516
2625
|
}
|
|
2626
|
+
|
|
2627
|
+
// For non-widget pages, update the browser URL so that a page
|
|
2628
|
+
// refresh reloads the correct session instead of starting fresh.
|
|
2629
|
+
if (!hasWidgetConfig && sessionId && config.sessionUrlTemplate && typeof history !== 'undefined' && history.replaceState) {
|
|
2630
|
+
var sessionUrl = config.sessionUrlTemplate.replace('{sessionId}', encodeURIComponent(sessionId));
|
|
2631
|
+
history.replaceState(null, '', sessionUrl);
|
|
2632
|
+
}
|
|
2517
2633
|
},
|
|
2518
2634
|
getSessionId: function getSessionId() {
|
|
2519
2635
|
var sessionId = this.inputElement ? this.inputElement.getAttribute('data-session-id') : null;
|
|
@@ -2522,10 +2638,45 @@ window.openAIChatManager = function () {
|
|
|
2522
2638
|
}
|
|
2523
2639
|
return sessionId;
|
|
2524
2640
|
},
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2641
|
+
clearCopiedMessageState: function clearCopiedMessageState() {
|
|
2642
|
+
if (this.copyResetTimeoutId) {
|
|
2643
|
+
window.clearTimeout(this.copyResetTimeoutId);
|
|
2644
|
+
this.copyResetTimeoutId = null;
|
|
2645
|
+
}
|
|
2646
|
+
if (this.activeCopyButton) {
|
|
2647
|
+
this.setCopyButtonState(this.activeCopyButton, false);
|
|
2648
|
+
this.activeCopyButton = null;
|
|
2649
|
+
}
|
|
2650
|
+
this.copiedMessageIndex = -1;
|
|
2651
|
+
},
|
|
2652
|
+
copyResponse: function copyResponse(message, index, event) {
|
|
2653
|
+
var _ref25,
|
|
2654
|
+
_message$copyContent,
|
|
2655
|
+
_event$target,
|
|
2656
|
+
_event$target$closest,
|
|
2657
|
+
_this23 = this;
|
|
2658
|
+
var text = message && _typeof(message) === 'object' ? (_ref25 = (_message$copyContent = message.copyContent) !== null && _message$copyContent !== void 0 ? _message$copyContent : message.content) !== null && _ref25 !== void 0 ? _ref25 : '' : message !== null && message !== void 0 ? message : '';
|
|
2659
|
+
var button = (event === null || event === void 0 ? void 0 : event.currentTarget) || (event === null || event === void 0 || (_event$target = event.target) === null || _event$target === void 0 || (_event$target$closest = _event$target.closest) === null || _event$target$closest === void 0 ? void 0 : _event$target$closest.call(_event$target, '[data-copy-message-index]')) || null;
|
|
2660
|
+
navigator.clipboard.writeText(text).then(function () {
|
|
2661
|
+
_this23.clearCopiedMessageState();
|
|
2662
|
+
_this23.copiedMessageIndex = typeof index === 'number' ? index : -1;
|
|
2663
|
+
_this23.activeCopyButton = button;
|
|
2664
|
+
if (button) {
|
|
2665
|
+
_this23.setCopyButtonState(button, true);
|
|
2666
|
+
} else {
|
|
2667
|
+
_this23.$nextTick(function () {
|
|
2668
|
+
return _this23.updateCopyButtons();
|
|
2669
|
+
});
|
|
2670
|
+
}
|
|
2671
|
+
_this23.copyResetTimeoutId = window.setTimeout(function () {
|
|
2672
|
+
_this23.clearCopiedMessageState();
|
|
2673
|
+
_this23.$nextTick(function () {
|
|
2674
|
+
return _this23.updateCopyButtons();
|
|
2675
|
+
});
|
|
2676
|
+
}, Number(config.copyResetDelayMs) || 2000);
|
|
2677
|
+
})["catch"](function (err) {
|
|
2678
|
+
return console.error('Failed to copy response:', err);
|
|
2679
|
+
});
|
|
2529
2680
|
},
|
|
2530
2681
|
updateFeedbackIcons: function updateFeedbackIcons(container, userRating) {
|
|
2531
2682
|
if (!container) {
|
|
@@ -2620,6 +2771,12 @@ window.openAIChatManager = function () {
|
|
|
2620
2771
|
// Reserved for future use — volume-based interrupt detection
|
|
2621
2772
|
// no longer mutes tracks; browser echo cancellation handles echo.
|
|
2622
2773
|
},
|
|
2774
|
+
copiedMessageIndex: function copiedMessageIndex() {
|
|
2775
|
+
var _this24 = this;
|
|
2776
|
+
this.$nextTick(function () {
|
|
2777
|
+
return _this24.updateCopyButtons();
|
|
2778
|
+
});
|
|
2779
|
+
},
|
|
2623
2780
|
isConversationMode: function isConversationMode(active) {
|
|
2624
2781
|
// Hide/show mic button.
|
|
2625
2782
|
if (this.micButton) {
|
|
@@ -2641,22 +2798,23 @@ window.openAIChatManager = function () {
|
|
|
2641
2798
|
}
|
|
2642
2799
|
},
|
|
2643
2800
|
mounted: function mounted() {
|
|
2644
|
-
var
|
|
2801
|
+
var _this25 = this;
|
|
2645
2802
|
_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0() {
|
|
2646
2803
|
var isInitialized;
|
|
2647
2804
|
return _regenerator().w(function (_context0) {
|
|
2648
2805
|
while (1) switch (_context0.n) {
|
|
2649
2806
|
case 0:
|
|
2650
2807
|
_context0.n = 1;
|
|
2651
|
-
return
|
|
2808
|
+
return _this25.startConnection();
|
|
2652
2809
|
case 1:
|
|
2653
|
-
isInitialized =
|
|
2810
|
+
isInitialized = _this25.initializeApp();
|
|
2654
2811
|
if (isInitialized && hasWidgetConfig && widgetBehavior && typeof widgetBehavior.onMounted === 'function') {
|
|
2655
|
-
widgetBehavior.onMounted(
|
|
2812
|
+
widgetBehavior.onMounted(_this25, config);
|
|
2656
2813
|
}
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2814
|
+
_this25.$nextTick(function () {
|
|
2815
|
+
_this25.updateCopyButtons();
|
|
2816
|
+
refreshFontAwesomeIcons(_this25.$el);
|
|
2817
|
+
_this25.fontAwesomeObserver = observeFontAwesomeIcons(_this25.$el);
|
|
2660
2818
|
});
|
|
2661
2819
|
case 2:
|
|
2662
2820
|
return _context0.a(2);
|
|
@@ -2673,6 +2831,7 @@ window.openAIChatManager = function () {
|
|
|
2673
2831
|
this.fontAwesomeObserver.disconnect();
|
|
2674
2832
|
this.fontAwesomeObserver = null;
|
|
2675
2833
|
}
|
|
2834
|
+
this.clearCopiedMessageState();
|
|
2676
2835
|
this.stopAudio(false);
|
|
2677
2836
|
if (this.stream) {
|
|
2678
2837
|
this.stream.dispose();
|
|
@@ -2693,8 +2852,151 @@ window.openAIChatManager = function () {
|
|
|
2693
2852
|
}
|
|
2694
2853
|
return app;
|
|
2695
2854
|
};
|
|
2855
|
+
var autoInitializeSelector = '[data-coreai-chat-config],[data-coreai-chat-app-element-selector]';
|
|
2856
|
+
function getAttributeValue(element, attributeName) {
|
|
2857
|
+
var value = element.getAttribute(attributeName);
|
|
2858
|
+
return value === null || value === '' ? null : value;
|
|
2859
|
+
}
|
|
2860
|
+
function parseBooleanAttributeValue(value) {
|
|
2861
|
+
if (value === null || value === undefined) {
|
|
2862
|
+
return null;
|
|
2863
|
+
}
|
|
2864
|
+
if (typeof value === 'boolean') {
|
|
2865
|
+
return value;
|
|
2866
|
+
}
|
|
2867
|
+
var normalized = String(value).trim().toLowerCase();
|
|
2868
|
+
if (normalized === 'true') {
|
|
2869
|
+
return true;
|
|
2870
|
+
}
|
|
2871
|
+
if (normalized === 'false') {
|
|
2872
|
+
return false;
|
|
2873
|
+
}
|
|
2874
|
+
return null;
|
|
2875
|
+
}
|
|
2876
|
+
function parseJsonAttribute(element, attributeName, description) {
|
|
2877
|
+
var rawValue = getAttributeValue(element, attributeName);
|
|
2878
|
+
if (!rawValue) {
|
|
2879
|
+
return null;
|
|
2880
|
+
}
|
|
2881
|
+
try {
|
|
2882
|
+
return JSON.parse(rawValue);
|
|
2883
|
+
} catch (error) {
|
|
2884
|
+
console.error('Failed to parse ' + description + ' JSON.', error);
|
|
2885
|
+
return null;
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
function buildConfigFromDataAttributes(element, options) {
|
|
2889
|
+
var _parseJsonAttribute, _parseJsonAttribute2;
|
|
2890
|
+
var settings = options || {};
|
|
2891
|
+
if (element.hasAttribute('data-coreai-chat-widget-container-selector') && settings.allowWidgetHost !== true) {
|
|
2892
|
+
return null;
|
|
2893
|
+
}
|
|
2894
|
+
var appElementSelector = getAttributeValue(element, 'data-coreai-chat-app-element-selector');
|
|
2895
|
+
if (!appElementSelector) {
|
|
2896
|
+
return null;
|
|
2897
|
+
}
|
|
2898
|
+
var config = {
|
|
2899
|
+
signalRHubUrl: getAttributeValue(element, 'data-coreai-chat-signalr-hub-url'),
|
|
2900
|
+
appElementSelector: appElementSelector,
|
|
2901
|
+
chatContainerElementSelector: getAttributeValue(element, 'data-coreai-chat-container-element-selector'),
|
|
2902
|
+
inputElementSelector: getAttributeValue(element, 'data-coreai-chat-input-element-selector'),
|
|
2903
|
+
sendButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-send-button-element-selector'),
|
|
2904
|
+
placeholderElementSelector: getAttributeValue(element, 'data-coreai-chat-placeholder-element-selector'),
|
|
2905
|
+
messages: (_parseJsonAttribute = parseJsonAttribute(element, 'data-coreai-chat-messages', 'CoreAI chat messages')) !== null && _parseJsonAttribute !== void 0 ? _parseJsonAttribute : undefined,
|
|
2906
|
+
chatMode: getAttributeValue(element, 'data-coreai-chat-mode'),
|
|
2907
|
+
micButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-mic-button-element-selector'),
|
|
2908
|
+
conversationButtonElementSelector: getAttributeValue(element, 'data-coreai-chat-conversation-button-element-selector'),
|
|
2909
|
+
ttsVoiceName: getAttributeValue(element, 'data-coreai-chat-tts-voice-name'),
|
|
2910
|
+
documentBarSelector: getAttributeValue(element, 'data-coreai-chat-document-bar-selector'),
|
|
2911
|
+
uploadDocumentUrl: getAttributeValue(element, 'data-coreai-chat-upload-document-url'),
|
|
2912
|
+
removeDocumentUrl: getAttributeValue(element, 'data-coreai-chat-remove-document-url'),
|
|
2913
|
+
allowedExtensions: getAttributeValue(element, 'data-coreai-chat-allowed-extensions'),
|
|
2914
|
+
supportedExtensionsText: getAttributeValue(element, 'data-coreai-chat-supported-extensions-text'),
|
|
2915
|
+
existingDocuments: (_parseJsonAttribute2 = parseJsonAttribute(element, 'data-coreai-chat-existing-documents', 'CoreAI chat existing documents')) !== null && _parseJsonAttribute2 !== void 0 ? _parseJsonAttribute2 : undefined,
|
|
2916
|
+
initialPrompt: getAttributeValue(element, 'data-coreai-chat-initial-prompt'),
|
|
2917
|
+
sessionUrlTemplate: getAttributeValue(element, 'data-coreai-chat-session-url-template'),
|
|
2918
|
+
userLabel: getAttributeValue(element, 'data-coreai-chat-user-label'),
|
|
2919
|
+
assistantLabel: getAttributeValue(element, 'data-coreai-chat-assistant-label'),
|
|
2920
|
+
copyTitle: getAttributeValue(element, 'data-coreai-chat-copy-title'),
|
|
2921
|
+
copiedTitle: getAttributeValue(element, 'data-coreai-chat-copied-title')
|
|
2922
|
+
};
|
|
2923
|
+
var booleanAttributes = {
|
|
2924
|
+
metricsEnabled: 'data-coreai-chat-metrics-enabled',
|
|
2925
|
+
textToSpeechEnabled: 'data-coreai-chat-text-to-speech-enabled',
|
|
2926
|
+
sessionDocumentsEnabled: 'data-coreai-chat-session-documents-enabled',
|
|
2927
|
+
singleResponseMode: 'data-coreai-chat-single-response-mode'
|
|
2928
|
+
};
|
|
2929
|
+
Object.keys(booleanAttributes).forEach(function (key) {
|
|
2930
|
+
var parsed = parseBooleanAttributeValue(getAttributeValue(element, booleanAttributes[key]));
|
|
2931
|
+
if (parsed !== null) {
|
|
2932
|
+
config[key] = parsed;
|
|
2933
|
+
}
|
|
2934
|
+
});
|
|
2935
|
+
return compactObject(config);
|
|
2936
|
+
}
|
|
2937
|
+
function buildConfigFromElement(element, options) {
|
|
2938
|
+
var jsonConfig = parseJsonAttribute(element, 'data-coreai-chat-config', 'CoreAI chat config');
|
|
2939
|
+
var attributeConfig = buildConfigFromDataAttributes(element, options);
|
|
2940
|
+
if (!jsonConfig && !attributeConfig) {
|
|
2941
|
+
return null;
|
|
2942
|
+
}
|
|
2943
|
+
return Object.assign({}, jsonConfig || {}, attributeConfig || {});
|
|
2944
|
+
}
|
|
2945
|
+
function initializeFromElement(element) {
|
|
2946
|
+
if (!element || element.dataset.coreAiChatInitialized === 'true') {
|
|
2947
|
+
return element ? element.__coreAIChatApp || null : null;
|
|
2948
|
+
}
|
|
2949
|
+
var config = buildConfigFromElement(element);
|
|
2950
|
+
if (!config) {
|
|
2951
|
+
return null;
|
|
2952
|
+
}
|
|
2953
|
+
var app = initialize(config);
|
|
2954
|
+
if (!app) {
|
|
2955
|
+
return null;
|
|
2956
|
+
}
|
|
2957
|
+
element.dataset.coreAiChatInitialized = 'true';
|
|
2958
|
+
element.__coreAIChatApp = app;
|
|
2959
|
+
return app;
|
|
2960
|
+
}
|
|
2961
|
+
function scanForAutoInitialization(root) {
|
|
2962
|
+
if (!root || typeof root.querySelectorAll !== 'function') {
|
|
2963
|
+
return;
|
|
2964
|
+
}
|
|
2965
|
+
if (typeof root.matches === 'function' && root.matches(autoInitializeSelector)) {
|
|
2966
|
+
initializeFromElement(root);
|
|
2967
|
+
}
|
|
2968
|
+
root.querySelectorAll(autoInitializeSelector).forEach(initializeFromElement);
|
|
2969
|
+
}
|
|
2970
|
+
function startAutoInitialization() {
|
|
2971
|
+
scanForAutoInitialization(document);
|
|
2972
|
+
if (typeof MutationObserver === 'undefined') {
|
|
2973
|
+
return;
|
|
2974
|
+
}
|
|
2975
|
+
var observer = new MutationObserver(function (mutations) {
|
|
2976
|
+
mutations.forEach(function (mutation) {
|
|
2977
|
+
mutation.addedNodes.forEach(function (node) {
|
|
2978
|
+
if (node && node.nodeType === 1) {
|
|
2979
|
+
scanForAutoInitialization(node);
|
|
2980
|
+
}
|
|
2981
|
+
});
|
|
2982
|
+
});
|
|
2983
|
+
});
|
|
2984
|
+
observer.observe(document.body, {
|
|
2985
|
+
childList: true,
|
|
2986
|
+
subtree: true
|
|
2987
|
+
});
|
|
2988
|
+
}
|
|
2989
|
+
if (document.readyState === 'loading') {
|
|
2990
|
+
document.addEventListener('DOMContentLoaded', startAutoInitialization, {
|
|
2991
|
+
once: true
|
|
2992
|
+
});
|
|
2993
|
+
} else {
|
|
2994
|
+
startAutoInitialization();
|
|
2995
|
+
}
|
|
2696
2996
|
return {
|
|
2697
|
-
initialize: initialize
|
|
2997
|
+
initialize: initialize,
|
|
2998
|
+
initializeFromElement: initializeFromElement,
|
|
2999
|
+
buildConfigFromElement: buildConfigFromElement
|
|
2698
3000
|
};
|
|
2699
3001
|
}();
|
|
2700
3002
|
|