@crestapps/ai-chat-ui 1.0.0-preview.23 → 1.0.0-preview.34
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 +0 -4
- 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.js +56 -16
- package/dist/ai-chat.js.map +1 -1
- package/dist/ai-chat.min.js +1 -1
- package/dist/ai-chat.min.js.map +1 -1
- package/dist/chat-interaction.js +54 -10
- 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/package.json +1 -1
- package/README.md +0 -145
package/dist/chat-interaction.js
CHANGED
|
@@ -33,8 +33,8 @@ window.chatInteractionManager = function () {
|
|
|
33
33
|
downloadChartButtonText: 'Download',
|
|
34
34
|
codeCopiedText: 'Copied!',
|
|
35
35
|
assistantLabel: 'Assistant',
|
|
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)\"><
|
|
37
|
-
indicatorTemplate: "\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><
|
|
36
|
+
messageTemplate: "\n <div class=\"ai-chat-messages\">\n <div v-for=\"(message, index) in messages\" :key=\"index\" class=\"ai-chat-message-item\">\n <div>\n <div v-if=\"message.role === 'user'\" class=\"ai-chat-msg-role ai-chat-msg-role-user\">You</div>\n <div v-else-if=\"message.role !== 'indicator'\" :class=\"getAssistantRoleClasses(message)\">\n <span :class=\"getAssistantIconClasses(message, index)\"><i :class=\"getAssistantIcon(message)\"></i></span>\n {{ getAssistantLabel(message) }}\n </div>\n <div class=\"ai-chat-message-body lh-base\">\n <h4 v-if=\"message.title\">{{ message.title }}</h4>\n <div v-html=\"message.htmlContent\"></div>\n <ol v-if=\"message.citationReferences && message.citationReferences.length\" class=\"ai-chat-citation-list\">\n <li v-for=\"citation in message.citationReferences\" :key=\"'citation-' + (citation.referenceKey || citation.displayIndex)\" class=\"ai-chat-citation-item\">\n <a v-if=\"citation.link\" :href=\"citation.link\" :target=\"citation.isDownload ? null : '_blank'\" :rel=\"citation.isDownload ? null : 'noopener noreferrer'\">{{ citation.label }}</a>\n <span v-else>{{ citation.label }}</span>\n </li>\n </ol>\n <span class=\"message-buttons-container\" v-if=\"!isIndicator(message)\">\n <button v-if=\"textToSpeechEnabled && !isConversationMode && message.role === 'assistant' && !message.isStreaming\" class=\"btn btn-sm btn-link text-secondary p-0 me-1 button-message-toolbox\" :class=\"{ 'tts-playing': ttsPlayingMessageIndex === index }\" :data-tts-message-index=\"index\" @click=\"toggleMessageTts(message, index)\" :title=\"ttsPlayingMessageIndex === index ? 'Pause audio' : 'Read aloud'\">\n <i :class=\"ttsPlayingMessageIndex === index ? 'fa-solid fa-circle-pause' : 'fa-solid fa-circle-play'\"></i>\n </button>\n <button class=\"btn btn-sm btn-link text-secondary p-0 button-message-toolbox\" @click=\"copyResponse(message)\" title=\"Click here to copy response to clipboard.\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n <div v-for=\"notification in notifications\" :key=\"'notif-' + notification.type\" class=\"ai-chat-notification\" :class=\"'ai-chat-notification-' + (notification.type || 'info') + ' ' + (notification.cssClass || '')\">\n <div class=\"ai-chat-notification-content\">\n <i v-if=\"notification.icon\" :class=\"notification.icon\" class=\"ai-chat-notification-icon\"></i>\n <span class=\"ai-chat-notification-text\">{{ notification.content }}</span>\n <button v-if=\"notification.dismissible\" class=\"btn btn-sm btn-link p-0 ms-2 ai-chat-notification-dismiss\" @click=\"dismissNotification(notification.type)\" title=\"Dismiss\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div v-if=\"notification.actions && notification.actions.length\" class=\"ai-chat-notification-actions\">\n <button v-for=\"action in notification.actions\" :key=\"action.name\" class=\"btn btn-sm\" :class=\"action.cssClass || 'btn-outline-secondary'\" @click=\"handleNotificationAction(notification.type, action.name)\">\n <i v-if=\"action.icon\" :class=\"action.icon\" class=\"me-1\"></i>\n {{ action.label }}\n </button>\n </div>\n </div>\n </div>\n ",
|
|
37
|
+
indicatorTemplate: "\n <div class=\"ai-chat-msg-role ai-chat-msg-role-assistant\">\n <span class=\"ai-streaming-icon\"><i class=\"fa fa-robot\" style=\"display: inline-block;\"></i></span>\n Assistant\n </div>\n ",
|
|
38
38
|
// Localizable strings
|
|
39
39
|
untitledText: 'Untitled',
|
|
40
40
|
clearHistoryTitle: 'Clear History',
|
|
@@ -59,6 +59,42 @@ window.chatInteractionManager = function () {
|
|
|
59
59
|
span.textContent = text;
|
|
60
60
|
return span.innerHTML;
|
|
61
61
|
}
|
|
62
|
+
function containsFontAwesomePlaceholders(root) {
|
|
63
|
+
if (!root || root.nodeType !== 1) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
var selector = 'i[class*="fa-"],i.fa,i.fas,i.far,i.fab';
|
|
67
|
+
if (typeof root.matches === 'function' && root.matches(selector)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
return typeof root.querySelector === 'function' && !!root.querySelector(selector);
|
|
71
|
+
}
|
|
72
|
+
function refreshFontAwesomeIcons(root) {
|
|
73
|
+
var fontAwesome = window.FontAwesome;
|
|
74
|
+
if (!containsFontAwesomePlaceholders(root) || !fontAwesome || !fontAwesome.dom || typeof fontAwesome.dom.i2svg !== 'function') {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
fontAwesome.dom.i2svg({
|
|
78
|
+
node: root
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function observeFontAwesomeIcons(root) {
|
|
82
|
+
if (!root || typeof MutationObserver === 'undefined') {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
var observer = new MutationObserver(function (mutations) {
|
|
86
|
+
mutations.forEach(function (mutation) {
|
|
87
|
+
mutation.addedNodes.forEach(function (node) {
|
|
88
|
+
refreshFontAwesomeIcons(node);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
observer.observe(root, {
|
|
93
|
+
childList: true,
|
|
94
|
+
subtree: true
|
|
95
|
+
});
|
|
96
|
+
return observer;
|
|
97
|
+
}
|
|
62
98
|
function normalizeReference(reference) {
|
|
63
99
|
var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$title, _ref4, _normalized$link, _ref5, _normalized$reference;
|
|
64
100
|
if (!reference || _typeof(reference) !== 'object') {
|
|
@@ -247,7 +283,7 @@ window.chatInteractionManager = function () {
|
|
|
247
283
|
highlighted = escapeHtmlEntities(code);
|
|
248
284
|
}
|
|
249
285
|
var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';
|
|
250
|
-
return "<div class=\"ai-code-block\"><div class=\"ai-code-header\"><span class=\"ai-code-lang\"><
|
|
286
|
+
return "<div class=\"ai-code-block\"><div class=\"ai-code-header\"><span class=\"ai-code-lang\"><i class=\"fa-solid fa-code\"></i> ".concat(langDisplay, "</span><button type=\"button\" class=\"ai-code-copy-btn\" title=\"Copy code\"><i class=\"fa-regular fa-copy\"></i></button></div><pre><code class=\"hljs").concat(lang ? ' language-' + lang : '', "\">").concat(highlighted, "</code></pre></div>");
|
|
251
287
|
};
|
|
252
288
|
|
|
253
289
|
// Custom image renderer for generated images with thumbnail styling and download button.
|
|
@@ -257,7 +293,7 @@ window.chatInteractionManager = function () {
|
|
|
257
293
|
if (!src) return '';
|
|
258
294
|
var alt = data.text || defaultConfig.generatedImageAltText;
|
|
259
295
|
var maxWidth = defaultConfig.generatedImageMaxWidth;
|
|
260
|
-
return "<div class=\"generated-image-container\">\n <img src=\"".concat(src, "\" alt=\"").concat(alt, "\" class=\"img-thumbnail\" style=\"max-width: ").concat(maxWidth, "px; height: auto;\" />\n <div class=\"mt-2\">\n <a href=\"").concat(src, "\" target=\"_blank\" download=\"").concat(alt, "\" title=\"").concat(defaultConfig.downloadImageTitle, "\" class=\"btn btn-sm btn-outline-secondary ai-download-image\">\n <
|
|
296
|
+
return "<div class=\"generated-image-container\">\n <img src=\"".concat(src, "\" alt=\"").concat(alt, "\" class=\"img-thumbnail\" style=\"max-width: ").concat(maxWidth, "px; height: auto;\" />\n <div class=\"mt-2\">\n <a href=\"").concat(src, "\" target=\"_blank\" download=\"").concat(alt, "\" title=\"").concat(defaultConfig.downloadImageTitle, "\" class=\"btn btn-sm btn-outline-secondary ai-download-image\">\n <i class=\"fa-solid fa-download\"></i>\n </a>\n </div>\n </div>");
|
|
261
297
|
};
|
|
262
298
|
|
|
263
299
|
// Chart counter for unique IDs
|
|
@@ -269,7 +305,7 @@ window.chatInteractionManager = function () {
|
|
|
269
305
|
// Global chart config map shared with ai-chat.js
|
|
270
306
|
window.__chartConfigs = window.__chartConfigs || {};
|
|
271
307
|
function createChartHtml(chartId) {
|
|
272
|
-
return "<div class=\"chart-container\" style=\"position: relative; width: 100%; max-width: 560px; min-height: 420px;\">" + "<canvas id=\"".concat(chartId, "\"></canvas>") + "</div>" + "<div class=\"mt-2\">" + "<button type=\"button\" class=\"btn btn-sm btn-outline-secondary download-chart-btn\" data-chart-id=\"".concat(chartId, "\" title=\"").concat(defaultConfig.downloadChartTitle, "\">") + "<
|
|
308
|
+
return "<div class=\"chart-container\" style=\"position: relative; width: 100%; max-width: 560px; min-height: 420px;\">" + "<canvas id=\"".concat(chartId, "\"></canvas>") + "</div>" + "<div class=\"mt-2\">" + "<button type=\"button\" class=\"btn btn-sm btn-outline-secondary download-chart-btn\" data-chart-id=\"".concat(chartId, "\" title=\"").concat(defaultConfig.downloadChartTitle, "\">") + "<i class=\"fa-solid fa-download\"></i> ".concat(defaultConfig.downloadChartButtonText) + "</button>" + "</div>";
|
|
273
309
|
}
|
|
274
310
|
|
|
275
311
|
// Register [chart:{...json...}] as a native marked block extension so the
|
|
@@ -1063,7 +1099,7 @@ window.chatInteractionManager = function () {
|
|
|
1063
1099
|
buttons.forEach(function (button) {
|
|
1064
1100
|
var buttonIndex = Number(button.getAttribute('data-tts-message-index'));
|
|
1065
1101
|
var isPlaying = buttonIndex === _this7.ttsPlayingMessageIndex;
|
|
1066
|
-
var iconHtml = isPlaying ? '<
|
|
1102
|
+
var iconHtml = isPlaying ? '<i class="fa-solid fa-circle-pause"></i>' : '<i class="fa-solid fa-circle-play"></i>';
|
|
1067
1103
|
button.classList.toggle('tts-playing', isPlaying);
|
|
1068
1104
|
button.setAttribute('title', isPlaying ? 'Pause audio' : 'Read aloud');
|
|
1069
1105
|
button.replaceChildren(DOMPurify.sanitize(iconHtml, {
|
|
@@ -1792,9 +1828,9 @@ window.chatInteractionManager = function () {
|
|
|
1792
1828
|
if (codeEl) {
|
|
1793
1829
|
navigator.clipboard.writeText(codeEl.textContent);
|
|
1794
1830
|
var copiedText = config.codeCopiedText || 'Copied!';
|
|
1795
|
-
btn.innerHTML = '<
|
|
1831
|
+
btn.innerHTML = '<i class="fa-solid fa-check"></i> ' + copiedText;
|
|
1796
1832
|
setTimeout(function () {
|
|
1797
|
-
btn.innerHTML = '<
|
|
1833
|
+
btn.innerHTML = '<i class="fa-regular fa-copy"></i>';
|
|
1798
1834
|
}, 2000);
|
|
1799
1835
|
}
|
|
1800
1836
|
});
|
|
@@ -2093,10 +2129,10 @@ window.chatInteractionManager = function () {
|
|
|
2093
2129
|
}
|
|
2094
2130
|
if (this.isRecording) {
|
|
2095
2131
|
this.micButton.classList.add('stt-recording');
|
|
2096
|
-
this.micButton.innerHTML = '<
|
|
2132
|
+
this.micButton.innerHTML = '<i class="fa-solid fa-stop"></i>';
|
|
2097
2133
|
} else {
|
|
2098
2134
|
this.micButton.classList.remove('stt-recording');
|
|
2099
|
-
this.micButton.innerHTML = '<
|
|
2135
|
+
this.micButton.innerHTML = '<i class="fa-solid fa-microphone"></i>';
|
|
2100
2136
|
}
|
|
2101
2137
|
}
|
|
2102
2138
|
},
|
|
@@ -2130,6 +2166,10 @@ window.chatInteractionManager = function () {
|
|
|
2130
2166
|
return _this21.startConnection();
|
|
2131
2167
|
case 1:
|
|
2132
2168
|
_this21.initializeApp();
|
|
2169
|
+
_this21.$nextTick(function () {
|
|
2170
|
+
refreshFontAwesomeIcons(_this21.$el);
|
|
2171
|
+
_this21.fontAwesomeObserver = observeFontAwesomeIcons(_this21.$el);
|
|
2172
|
+
});
|
|
2133
2173
|
case 2:
|
|
2134
2174
|
return _context5.a(2);
|
|
2135
2175
|
}
|
|
@@ -2141,6 +2181,10 @@ window.chatInteractionManager = function () {
|
|
|
2141
2181
|
beforeUnmount: function beforeUnmount() {
|
|
2142
2182
|
window.removeEventListener('beforeunload', this.handleBeforeUnload);
|
|
2143
2183
|
window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);
|
|
2184
|
+
if (this.fontAwesomeObserver) {
|
|
2185
|
+
this.fontAwesomeObserver.disconnect();
|
|
2186
|
+
this.fontAwesomeObserver = null;
|
|
2187
|
+
}
|
|
2144
2188
|
this.stopAudio(false);
|
|
2145
2189
|
if (this.stream) {
|
|
2146
2190
|
this.stream.dispose();
|