@crestapps/ai-chat-ui 2.0.0-preview.190 → 2.0.0-preview.193
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.css +91 -0
- package/dist/ai-chat.css.map +1 -1
- package/dist/ai-chat.js +320 -129
- 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.js +239 -119
- 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-markers.js +439 -0
- package/dist/chat-markers.js.map +1 -0
- package/dist/chat-markers.min.js +2 -0
- package/dist/chat-markers.min.js.map +1 -0
- package/dist/chat-widget.css +50 -0
- package/dist/chat-widget.css.map +1 -1
- package/dist/chat-widget.min.css +1 -1
- package/package.json +1 -1
package/dist/ai-chat.js
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
var _excluded = ["placeholder"];
|
|
7
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 }; })(); }
|
|
8
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); }
|
|
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); }
|
|
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); }); }; }
|
|
11
9
|
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
12
10
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
13
11
|
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
@@ -15,6 +13,8 @@ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(
|
|
|
15
13
|
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
14
|
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
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
|
+
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); }
|
|
17
|
+
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); }); }; }
|
|
18
18
|
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
19
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
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; } }
|
|
@@ -22,7 +22,25 @@ 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
|
-
|
|
25
|
+
/*
|
|
26
|
+
* Figure markers: the short labels the model writes, turned into pictures by the host.
|
|
27
|
+
*
|
|
28
|
+
* Retrieval hands the model a label -- [fig:1] -- and keeps the picture's real link in the message's reference
|
|
29
|
+
* map, the same way a text citation keeps its source behind "[doc:1]". A model asked to reproduce a long opaque
|
|
30
|
+
* identifier does not reproduce it: it copies the shape and substitutes ordinals, so links to figures that were
|
|
31
|
+
* never in the results came back as 404s. A label short enough to be written exactly, with the link put back
|
|
32
|
+
* here where the model cannot reach it, is what stops that.
|
|
33
|
+
*
|
|
34
|
+
* It sits on window rather than inside the manager below so the host can reach it, and so its rules can be
|
|
35
|
+
* exercised in a bare sandbox with no browser and no DOM -- see tests/realtime-client/figure-markers.test.js --
|
|
36
|
+
* exactly as window.CoreAIRealtime exposes the microphone gate's rules.
|
|
37
|
+
*
|
|
38
|
+
* The same block sits at the top of chat-interaction.js: the two chat clients are separate bundles that share no
|
|
39
|
+
* module of their own, and both render the same markdown. Change one, change the other.
|
|
40
|
+
*/
|
|
41
|
+
// CoreAIChatMarkers lives in chat-markers.js, which every chat surface loads before this file.
|
|
42
|
+
|
|
43
|
+
window.coreAIChatManager = function (_window$CoreAIChatMar, _window$CoreAIChatMar2, _window$CoreAIChatMar3, _window$CoreAIChatMar4, _window$CoreAIChatMar5, _window$CoreAIChatMar6, _window$CoreAIChatMar7, _window$CoreAIChatMar8, _window$CoreAIChatMar9, _window$CoreAIChatMar0) {
|
|
26
44
|
// Defaults (can be overridden by instanceConfig)
|
|
27
45
|
var defaultConfig = {
|
|
28
46
|
// UI defaults for generated media
|
|
@@ -127,7 +145,7 @@ window.coreAIChatManager = function () {
|
|
|
127
145
|
return Math.min(Math.max(value, min), max);
|
|
128
146
|
}
|
|
129
147
|
function normalizeReference(reference) {
|
|
130
|
-
var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$title, _ref4, _normalized$link, _ref5, _normalized$reference, _normalized$isGenerat;
|
|
148
|
+
var _ref, _normalized$index, _ref2, _normalized$text, _ref3, _normalized$title, _ref4, _normalized$link, _ref5, _normalized$reference, _normalized$isGenerat, _normalized$isImage;
|
|
131
149
|
if (!reference || _typeof(reference) !== 'object') {
|
|
132
150
|
return null;
|
|
133
151
|
}
|
|
@@ -138,6 +156,7 @@ window.coreAIChatManager = function () {
|
|
|
138
156
|
normalized.link = sanitizeUrl((_ref4 = (_normalized$link = normalized.link) !== null && _normalized$link !== void 0 ? _normalized$link : normalized.Link) !== null && _ref4 !== void 0 ? _ref4 : null);
|
|
139
157
|
normalized.referenceType = (_ref5 = (_normalized$reference = normalized.referenceType) !== null && _normalized$reference !== void 0 ? _normalized$reference : normalized.ReferenceType) !== null && _ref5 !== void 0 ? _ref5 : null;
|
|
140
158
|
normalized.isGenerated = ((_normalized$isGenerat = normalized.isGenerated) !== null && _normalized$isGenerat !== void 0 ? _normalized$isGenerat : normalized.IsGenerated) === true;
|
|
159
|
+
normalized.isImage = ((_normalized$isImage = normalized.isImage) !== null && _normalized$isImage !== void 0 ? _normalized$isImage : normalized.IsImage) === true;
|
|
141
160
|
return normalized;
|
|
142
161
|
}
|
|
143
162
|
function isDownloadCitationReference(reference) {
|
|
@@ -166,11 +185,95 @@ window.coreAIChatManager = function () {
|
|
|
166
185
|
}
|
|
167
186
|
return normalized;
|
|
168
187
|
}
|
|
188
|
+
|
|
189
|
+
// Installed at the top of this file so it can be unit tested without a browser; see the comment there.
|
|
190
|
+
|
|
191
|
+
/*
|
|
192
|
+
* Reads a JSON response body, or explains why it is not JSON.
|
|
193
|
+
*
|
|
194
|
+
* fetch follows a redirect silently and reports the page it landed on as a success, so an endpoint that
|
|
195
|
+
* answers "forbidden" with a redirect to a sign-in page arrives here as response.ok with HTML in it.
|
|
196
|
+
* Calling response.json() on that throws "unexpected character at line 1 column 1", which is what the
|
|
197
|
+
* reader was shown instead of being told they are not allowed to upload.
|
|
198
|
+
*
|
|
199
|
+
* Returns { ok, data, message }. A caller shows message when ok is false; it is never a parser error.
|
|
200
|
+
*/
|
|
201
|
+
function readJsonResponse(_x, _x2) {
|
|
202
|
+
return _readJsonResponse.apply(this, arguments);
|
|
203
|
+
}
|
|
204
|
+
function _readJsonResponse() {
|
|
205
|
+
_readJsonResponse = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0(response, fallbackMessage) {
|
|
206
|
+
var contentType, message, _t6, _t7;
|
|
207
|
+
return _regenerator().w(function (_context0) {
|
|
208
|
+
while (1) switch (_context0.p = _context0.n) {
|
|
209
|
+
case 0:
|
|
210
|
+
contentType = response.headers && response.headers.get('content-type') || '';
|
|
211
|
+
if (!(contentType.toLowerCase().indexOf('json') < 0)) {
|
|
212
|
+
_context0.n = 1;
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
// A redirect that landed somewhere else is the common case and worth naming, because the endpoint
|
|
216
|
+
// did not refuse -- something in front of it did.
|
|
217
|
+
message = response.redirected ? 'You may not be signed in, or you do not have permission for this. Please reload and try again.' : fallbackMessage;
|
|
218
|
+
return _context0.a(2, {
|
|
219
|
+
ok: false,
|
|
220
|
+
data: null,
|
|
221
|
+
message: message
|
|
222
|
+
});
|
|
223
|
+
case 1:
|
|
224
|
+
_context0.p = 1;
|
|
225
|
+
_context0.n = 2;
|
|
226
|
+
return response.json();
|
|
227
|
+
case 2:
|
|
228
|
+
_t6 = _context0.v;
|
|
229
|
+
return _context0.a(2, {
|
|
230
|
+
ok: true,
|
|
231
|
+
data: _t6,
|
|
232
|
+
message: null
|
|
233
|
+
});
|
|
234
|
+
case 3:
|
|
235
|
+
_context0.p = 3;
|
|
236
|
+
_t7 = _context0.v;
|
|
237
|
+
return _context0.a(2, {
|
|
238
|
+
ok: false,
|
|
239
|
+
data: null,
|
|
240
|
+
message: fallbackMessage
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}, _callee0, null, [[1, 3]]);
|
|
244
|
+
}));
|
|
245
|
+
return _readJsonResponse.apply(this, arguments);
|
|
246
|
+
}
|
|
247
|
+
var expandImageMarkers = window.CoreAIChatMarkers.expandImageMarkers;
|
|
169
248
|
function getCitationLabel(reference, key) {
|
|
170
249
|
return reference.title || reference.text || key;
|
|
171
250
|
}
|
|
251
|
+
|
|
252
|
+
// Which references are one citation, and how a repeated marker reads, are statements about strings and
|
|
253
|
+
// live in chat-markers.js so every chat surface numbers them the same way. Without the module each
|
|
254
|
+
// reference keeps an identity of its own and nothing merges, which is the numbering this script had
|
|
255
|
+
// before it.
|
|
256
|
+
var unmergedCitationCount = 0;
|
|
257
|
+
var citationIdentity = (_window$CoreAIChatMar = (_window$CoreAIChatMar2 = window.CoreAIChatMarkers) === null || _window$CoreAIChatMar2 === void 0 ? void 0 : _window$CoreAIChatMar2.citationIdentity) !== null && _window$CoreAIChatMar !== void 0 ? _window$CoreAIChatMar : function () {
|
|
258
|
+
return "unmerged-".concat(++unmergedCitationCount);
|
|
259
|
+
};
|
|
260
|
+
var splitCombinedCitations = (_window$CoreAIChatMar3 = (_window$CoreAIChatMar4 = window.CoreAIChatMarkers) === null || _window$CoreAIChatMar4 === void 0 ? void 0 : _window$CoreAIChatMar4.splitCombinedCitations) !== null && _window$CoreAIChatMar3 !== void 0 ? _window$CoreAIChatMar3 : function (content) {
|
|
261
|
+
return content;
|
|
262
|
+
};
|
|
263
|
+
var collapseRepeatedCitations = (_window$CoreAIChatMar5 = (_window$CoreAIChatMar6 = window.CoreAIChatMarkers) === null || _window$CoreAIChatMar6 === void 0 ? void 0 : _window$CoreAIChatMar6.collapseRepeatedCitations) !== null && _window$CoreAIChatMar5 !== void 0 ? _window$CoreAIChatMar5 : function (html) {
|
|
264
|
+
return html;
|
|
265
|
+
};
|
|
266
|
+
var separateAdjacentCitations = (_window$CoreAIChatMar7 = (_window$CoreAIChatMar8 = window.CoreAIChatMarkers) === null || _window$CoreAIChatMar8 === void 0 ? void 0 : _window$CoreAIChatMar8.separateAdjacentCitations) !== null && _window$CoreAIChatMar7 !== void 0 ? _window$CoreAIChatMar7 : function (html) {
|
|
267
|
+
return html;
|
|
268
|
+
};
|
|
269
|
+
var citationMarkerHtml = (_window$CoreAIChatMar9 = (_window$CoreAIChatMar0 = window.CoreAIChatMarkers) === null || _window$CoreAIChatMar0 === void 0 ? void 0 : _window$CoreAIChatMar0.citationMarkerHtml) !== null && _window$CoreAIChatMar9 !== void 0 ? _window$CoreAIChatMar9 : function (displayIndex) {
|
|
270
|
+
return "<sup>".concat(displayIndex, "</sup>");
|
|
271
|
+
};
|
|
172
272
|
function buildCitationDisplay(content, references) {
|
|
173
|
-
|
|
273
|
+
// Before anything looks for a reference key, the combined form the model tends to write is split into
|
|
274
|
+
// the keys it means. A key that is not found is not replaced, and an unreplaced key reaches the reader
|
|
275
|
+
// as a raw marker mid-sentence.
|
|
276
|
+
var processedContent = splitCombinedCitations((content || '').trim());
|
|
174
277
|
var messageReferences = normalizeReferences(references);
|
|
175
278
|
var referenceEntries = Object.entries(messageReferences);
|
|
176
279
|
if (!referenceEntries.length) {
|
|
@@ -211,6 +314,8 @@ window.coreAIChatManager = function () {
|
|
|
211
314
|
return a.index - b.index;
|
|
212
315
|
});
|
|
213
316
|
var citations = [];
|
|
317
|
+
var citationsByIdentity = new Map();
|
|
318
|
+
var placeholders = [];
|
|
214
319
|
var displayIndex = 1;
|
|
215
320
|
var _iterator = _createForOfIteratorHelper(citedRefs),
|
|
216
321
|
_step;
|
|
@@ -219,28 +324,48 @@ window.coreAIChatManager = function () {
|
|
|
219
324
|
var _step$value = _slicedToArray(_step.value, 2),
|
|
220
325
|
key = _step$value[0],
|
|
221
326
|
value = _step$value[1];
|
|
222
|
-
var
|
|
327
|
+
var label = getCitationLabel(value, key);
|
|
328
|
+
var link = value.link || null;
|
|
329
|
+
var identity = citationIdentity(label, link);
|
|
330
|
+
var citation = citationsByIdentity.get(identity);
|
|
331
|
+
|
|
332
|
+
// Every reference still has its key replaced, so the text never keeps a raw key; what the merge
|
|
333
|
+
// changes is only how many numbers the reader is given for them.
|
|
334
|
+
if (!citation) {
|
|
335
|
+
citation = {
|
|
336
|
+
referenceKey: key,
|
|
337
|
+
referenceKeys: [],
|
|
338
|
+
displayIndex: displayIndex++,
|
|
339
|
+
label: label,
|
|
340
|
+
link: link,
|
|
341
|
+
isDownload: isDownloadCitationReference(value)
|
|
342
|
+
};
|
|
343
|
+
citationsByIdentity.set(identity, citation);
|
|
344
|
+
citations.push(citation);
|
|
345
|
+
}
|
|
346
|
+
citation.referenceKeys.push(key);
|
|
347
|
+
var placeholder = "__CITE_".concat(citation.displayIndex, "_").concat(value.index || citation.displayIndex, "__");
|
|
223
348
|
processedContent = processedContent.replaceAll(key, placeholder);
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
displayIndex: displayIndex,
|
|
227
|
-
label:
|
|
228
|
-
link: value.link || null,
|
|
229
|
-
isDownload: isDownloadCitationReference(value),
|
|
230
|
-
placeholder: placeholder
|
|
349
|
+
placeholders.push({
|
|
350
|
+
placeholder: placeholder,
|
|
351
|
+
displayIndex: citation.displayIndex,
|
|
352
|
+
label: citation.label
|
|
231
353
|
});
|
|
232
|
-
displayIndex++;
|
|
233
354
|
}
|
|
234
355
|
} catch (err) {
|
|
235
356
|
_iterator.e(err);
|
|
236
357
|
} finally {
|
|
237
358
|
_iterator.f();
|
|
238
359
|
}
|
|
239
|
-
for (var _i2 = 0,
|
|
240
|
-
var
|
|
241
|
-
processedContent = processedContent.replaceAll(
|
|
360
|
+
for (var _i2 = 0, _placeholders = placeholders; _i2 < _placeholders.length; _i2++) {
|
|
361
|
+
var entry = _placeholders[_i2];
|
|
362
|
+
processedContent = processedContent.replaceAll(entry.placeholder, citationMarkerHtml(entry.displayIndex, entry.label));
|
|
242
363
|
}
|
|
243
|
-
|
|
364
|
+
|
|
365
|
+
// Merged citations can leave the same number twice over a sentence; that is collapsed before the
|
|
366
|
+
// commas go in, or the reader is given "1,1".
|
|
367
|
+
processedContent = collapseRepeatedCitations(processedContent);
|
|
368
|
+
processedContent = separateAdjacentCitations(processedContent);
|
|
244
369
|
|
|
245
370
|
// Generated files (such as exported tabular data) are always offered as a download even when
|
|
246
371
|
// the model does not cite them inline, so the user never loses access to the produced file.
|
|
@@ -253,6 +378,7 @@ window.coreAIChatManager = function () {
|
|
|
253
378
|
_value = _step2$value[1];
|
|
254
379
|
citations.push({
|
|
255
380
|
referenceKey: _key,
|
|
381
|
+
referenceKeys: [_key],
|
|
256
382
|
displayIndex: displayIndex,
|
|
257
383
|
label: getCitationLabel(_value, _key),
|
|
258
384
|
link: _value.link || null,
|
|
@@ -280,12 +406,27 @@ window.coreAIChatManager = function () {
|
|
|
280
406
|
if (!copyContent || !Array.isArray(citations) || citations.length === 0) {
|
|
281
407
|
return copyContent;
|
|
282
408
|
}
|
|
409
|
+
|
|
410
|
+
// Every key the citation absorbed is replaced, not just the first: a merged key left behind would
|
|
411
|
+
// reach the clipboard as the raw reference token the reader never saw on the page.
|
|
283
412
|
var _iterator3 = _createForOfIteratorHelper(citations),
|
|
284
413
|
_step3;
|
|
285
414
|
try {
|
|
286
415
|
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
416
|
+
var _citation$referenceKe;
|
|
287
417
|
var citation = _step3.value;
|
|
288
|
-
|
|
418
|
+
var _iterator5 = _createForOfIteratorHelper((_citation$referenceKe = citation.referenceKeys) !== null && _citation$referenceKe !== void 0 && _citation$referenceKe.length ? citation.referenceKeys : [citation.referenceKey]),
|
|
419
|
+
_step5;
|
|
420
|
+
try {
|
|
421
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
422
|
+
var key = _step5.value;
|
|
423
|
+
copyContent = copyContent.replaceAll(key, "[".concat(citation.displayIndex, "]"));
|
|
424
|
+
}
|
|
425
|
+
} catch (err) {
|
|
426
|
+
_iterator5.e(err);
|
|
427
|
+
} finally {
|
|
428
|
+
_iterator5.f();
|
|
429
|
+
}
|
|
289
430
|
}
|
|
290
431
|
} catch (err) {
|
|
291
432
|
_iterator3.e(err);
|
|
@@ -314,13 +455,20 @@ window.coreAIChatManager = function () {
|
|
|
314
455
|
function updateMessagePresentation(message, references) {
|
|
315
456
|
var messageReferences = normalizeReferences(references !== null && references !== void 0 ? references : message.references);
|
|
316
457
|
var rawContent = typeof message.rawContent === 'string' ? message.rawContent : typeof message.content === 'string' ? message.content : '';
|
|
317
|
-
|
|
458
|
+
// Figure markers become images before anything else reads the content: the citation pass looks for its
|
|
459
|
+
// own keys in what is left, and the markdown parser then sees an ordinary image.
|
|
460
|
+
var displayContent = expandImageMarkers(rawContent, messageReferences);
|
|
461
|
+
var citationDisplay = buildCitationDisplay(displayContent, messageReferences);
|
|
318
462
|
message.rawContent = rawContent;
|
|
319
463
|
message.content = rawContent;
|
|
320
464
|
message.displayContent = citationDisplay.content;
|
|
321
465
|
message.references = messageReferences;
|
|
322
466
|
message.citationReferences = citationDisplay.citations;
|
|
323
|
-
|
|
467
|
+
// Copied from the expanded content, so a copied answer carries the picture's link rather than a label
|
|
468
|
+
// that means nothing outside this page.
|
|
469
|
+
// Split here too: the copy is built from the expanded content rather than the display path's output,
|
|
470
|
+
// so a combined marker would otherwise survive into the clipboard as a raw key.
|
|
471
|
+
message.copyContent = buildCopyContent(splitCombinedCitations(displayContent), citationDisplay.citations);
|
|
324
472
|
message.htmlContent = parseMarkdownContent(citationDisplay.content, message);
|
|
325
473
|
return message;
|
|
326
474
|
}
|
|
@@ -364,7 +512,12 @@ window.coreAIChatManager = function () {
|
|
|
364
512
|
if (!src) return '';
|
|
365
513
|
var alt = data.text || defaultConfig.generatedImageAltText;
|
|
366
514
|
var maxWidth = defaultConfig.generatedImageMaxWidth;
|
|
367
|
-
|
|
515
|
+
// Spans, not divs. A figure marker is often written mid-sentence -- "Figures [fig:1], [fig:2] and
|
|
516
|
+
// [fig:3] show..." -- and a block element cannot sit inside a paragraph: the browser closes the <p>
|
|
517
|
+
// at the first one, so the sentence is torn into fragments and the commas between the markers are
|
|
518
|
+
// left stranded on their own lines. Inline-block keeps the figure looking exactly the same while
|
|
519
|
+
// remaining something a paragraph can legally contain.
|
|
520
|
+
return "<span class=\"generated-image-container\">\n <img src=\"".concat(src, "\" alt=\"").concat(alt, "\" class=\"img-thumbnail\" style=\"max-width: ").concat(maxWidth, "px; height: auto;\" />\n <span class=\"mt-2 d-block\">\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 </span>\n </span>");
|
|
368
521
|
};
|
|
369
522
|
|
|
370
523
|
// Chart counter for unique IDs
|
|
@@ -381,6 +534,11 @@ window.coreAIChatManager = function () {
|
|
|
381
534
|
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>";
|
|
382
535
|
}
|
|
383
536
|
|
|
537
|
+
// The marker itself is read by chat-markers.js, shared with every other chat surface, so the three of them
|
|
538
|
+
// cannot disagree about what a marker is. Everything below -- the container, the id scheme, the Chart.js
|
|
539
|
+
// call -- is this surface's own and legitimately differs from the others.
|
|
540
|
+
var findChartMarker = window.CoreAIChatMarkers.findChartMarker;
|
|
541
|
+
|
|
384
542
|
// Register [chart:{...json...}] as a native marked block extension so the
|
|
385
543
|
// markdown parser handles chart markers inline with surrounding text.
|
|
386
544
|
marked.use({
|
|
@@ -392,7 +550,7 @@ window.coreAIChatManager = function () {
|
|
|
392
550
|
return idx >= 0 ? idx : undefined;
|
|
393
551
|
},
|
|
394
552
|
tokenizer: function tokenizer(src) {
|
|
395
|
-
var extracted =
|
|
553
|
+
var extracted = findChartMarker(src);
|
|
396
554
|
if (!extracted || extracted.startIndex !== 0) {
|
|
397
555
|
return undefined;
|
|
398
556
|
}
|
|
@@ -415,69 +573,60 @@ window.coreAIChatManager = function () {
|
|
|
415
573
|
}]
|
|
416
574
|
});
|
|
417
575
|
|
|
418
|
-
//
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
576
|
+
// An image the assistant named but the server will not serve. The address is written by a language
|
|
577
|
+
// model from what retrieval handed it, so a mistyped or invented one is possible, and the browser's
|
|
578
|
+
// default for that is a broken-image icon captioned with the alt text -- which reads as a real picture
|
|
579
|
+
// that failed to arrive. Saying plainly that it could not be loaded is both truer and quieter.
|
|
580
|
+
//
|
|
581
|
+
// Wired here rather than as an inline onerror attribute because message bodies go through DOMPurify,
|
|
582
|
+
// which strips event-handler attributes.
|
|
583
|
+
function markBrokenImagesInMessage() {
|
|
584
|
+
// Scanning the document rather than one message, because the value threaded through the render
|
|
585
|
+
// path is the message DATA object -- the thing carrying content, references and pending charts --
|
|
586
|
+
// and not the element it was rendered into. Wiring is idempotent via the data-broken-wired mark,
|
|
587
|
+
// so re-scanning after each render costs a query over the handful of images already handled.
|
|
588
|
+
if (typeof document === 'undefined' || typeof requestAnimationFrame !== 'function') {
|
|
589
|
+
return;
|
|
424
590
|
}
|
|
425
591
|
|
|
426
|
-
//
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
escape = false;
|
|
443
|
-
continue;
|
|
444
|
-
}
|
|
445
|
-
if (ch === '\\') {
|
|
446
|
-
escape = true;
|
|
447
|
-
continue;
|
|
448
|
-
}
|
|
449
|
-
if (ch === '"') {
|
|
450
|
-
inString = false;
|
|
451
|
-
}
|
|
452
|
-
continue;
|
|
453
|
-
}
|
|
454
|
-
if (ch === '"') {
|
|
455
|
-
inString = true;
|
|
456
|
-
continue;
|
|
457
|
-
}
|
|
458
|
-
if (ch === '{') {
|
|
459
|
-
depth++;
|
|
460
|
-
} else if (ch === '}') {
|
|
461
|
-
depth--;
|
|
462
|
-
if (depth === 0) {
|
|
463
|
-
var jsonEnd = i;
|
|
464
|
-
// Expect closing bracket after JSON
|
|
465
|
-
var closeBracketIndex = text.indexOf(']', jsonEnd + 1);
|
|
466
|
-
if (closeBracketIndex < 0) {
|
|
467
|
-
return null;
|
|
592
|
+
// Deferred for the same reason the charts below are: the render that produced these elements has
|
|
593
|
+
// not necessarily been flushed to the DOM when this runs.
|
|
594
|
+
requestAnimationFrame(wireBrokenImageHandlers);
|
|
595
|
+
}
|
|
596
|
+
function wireBrokenImageHandlers() {
|
|
597
|
+
var images = document.querySelectorAll('.generated-image-container img:not([data-broken-wired])');
|
|
598
|
+
var _iterator6 = _createForOfIteratorHelper(images),
|
|
599
|
+
_step6;
|
|
600
|
+
try {
|
|
601
|
+
var _loop = function _loop() {
|
|
602
|
+
var image = _step6.value;
|
|
603
|
+
image.setAttribute('data-broken-wired', 'true');
|
|
604
|
+
image.addEventListener('error', function () {
|
|
605
|
+
var container = image.closest('.generated-image-container');
|
|
606
|
+
if (!container || container.dataset.brokenHandled) {
|
|
607
|
+
return;
|
|
468
608
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}
|
|
609
|
+
container.dataset.brokenHandled = 'true';
|
|
610
|
+
container.hidden = true;
|
|
611
|
+
var note = document.createElement('p');
|
|
612
|
+
note.className = 'text-muted small fst-italic mb-2';
|
|
613
|
+
note.textContent = image.alt ? "(the picture \"".concat(image.alt, "\" could not be loaded)") : '(that picture could not be loaded)';
|
|
614
|
+
container.insertAdjacentElement('afterend', note);
|
|
615
|
+
}, {
|
|
616
|
+
once: true
|
|
617
|
+
});
|
|
618
|
+
};
|
|
619
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
620
|
+
_loop();
|
|
476
621
|
}
|
|
622
|
+
} catch (err) {
|
|
623
|
+
_iterator6.e(err);
|
|
624
|
+
} finally {
|
|
625
|
+
_iterator6.f();
|
|
477
626
|
}
|
|
478
|
-
return null;
|
|
479
627
|
}
|
|
480
|
-
function
|
|
628
|
+
function renderMessageMedia(message) {
|
|
629
|
+
markBrokenImagesInMessage();
|
|
481
630
|
if (!message || !message._pendingCharts || !message._pendingCharts.length) {
|
|
482
631
|
return;
|
|
483
632
|
}
|
|
@@ -489,17 +638,17 @@ window.coreAIChatManager = function () {
|
|
|
489
638
|
// Defer to requestAnimationFrame so the browser has fully laid out the
|
|
490
639
|
// canvas elements before Chart.js reads their dimensions.
|
|
491
640
|
requestAnimationFrame(function () {
|
|
492
|
-
var
|
|
493
|
-
|
|
641
|
+
var _iterator7 = _createForOfIteratorHelper(charts),
|
|
642
|
+
_step7;
|
|
494
643
|
try {
|
|
495
|
-
for (
|
|
496
|
-
var c =
|
|
644
|
+
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
645
|
+
var c = _step7.value;
|
|
497
646
|
renderChartOnCanvas(c.chartId, c.config);
|
|
498
647
|
}
|
|
499
648
|
} catch (err) {
|
|
500
|
-
|
|
649
|
+
_iterator7.e(err);
|
|
501
650
|
} finally {
|
|
502
|
-
|
|
651
|
+
_iterator7.f();
|
|
503
652
|
}
|
|
504
653
|
});
|
|
505
654
|
}
|
|
@@ -562,11 +711,19 @@ window.coreAIChatManager = function () {
|
|
|
562
711
|
// Parse markdown content via marked (which natively handles [chart:...] markers
|
|
563
712
|
// through the registered extension) and collect pending chart configs for later
|
|
564
713
|
// Chart.js rendering.
|
|
714
|
+
// A markdown table becomes a bare <table>, which Bootstrap leaves completely unstyled: it renders
|
|
715
|
+
// as cramped, borderless text that reads as plain output rather than a table. Adding the framework's
|
|
716
|
+
// own classes styles it wherever Bootstrap is loaded, and the wrapper lets a wide table scroll on
|
|
717
|
+
// its own instead of stretching the conversation. Markdown tables cannot nest, so the plain
|
|
718
|
+
// replacement is safe.
|
|
719
|
+
function styleMarkdownTables(html) {
|
|
720
|
+
return html.replace(/<table>/g, '<div class="table-responsive"><table class="table table-sm table-bordered table-striped align-middle">').replace(/<\/table>/g, '</table></div>');
|
|
721
|
+
}
|
|
565
722
|
function parseMarkdownContent(content, message) {
|
|
566
723
|
_pendingCharts = [];
|
|
567
|
-
var html = marked.parse(content, {
|
|
724
|
+
var html = styleMarkdownTables(marked.parse(content, {
|
|
568
725
|
renderer: renderer
|
|
569
|
-
});
|
|
726
|
+
}));
|
|
570
727
|
message._pendingCharts = _pendingCharts.length > 0 ? _toConsumableArray(_pendingCharts) : [];
|
|
571
728
|
return DOMPurify.sanitize(html, {
|
|
572
729
|
ADD_TAGS: ['canvas'],
|
|
@@ -792,7 +949,7 @@ window.coreAIChatManager = function () {
|
|
|
792
949
|
return _context3.a(2);
|
|
793
950
|
case 2:
|
|
794
951
|
return _context3.a(2, _this.queueDocumentOperation(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
795
|
-
var sessionId, profileId, formData, i, response, errorText, uploadError, result, _t, _t2;
|
|
952
|
+
var sessionId, profileId, formData, i, response, errorText, uploadError, parsed, result, _t, _t2;
|
|
796
953
|
return _regenerator().w(function (_context2) {
|
|
797
954
|
while (1) switch (_context2.p = _context2.n) {
|
|
798
955
|
case 0:
|
|
@@ -865,9 +1022,24 @@ window.coreAIChatManager = function () {
|
|
|
865
1022
|
return _context2.a(2);
|
|
866
1023
|
case 9:
|
|
867
1024
|
_context2.n = 10;
|
|
868
|
-
return response.
|
|
1025
|
+
return readJsonResponse(response, 'Upload failed. Please try again.');
|
|
869
1026
|
case 10:
|
|
870
|
-
|
|
1027
|
+
parsed = _context2.v;
|
|
1028
|
+
if (parsed.ok) {
|
|
1029
|
+
_context2.n = 11;
|
|
1030
|
+
break;
|
|
1031
|
+
}
|
|
1032
|
+
console.error('Upload failed: response was not JSON.', {
|
|
1033
|
+
status: response.status,
|
|
1034
|
+
redirected: response.redirected
|
|
1035
|
+
});
|
|
1036
|
+
_this.uploadErrors = [{
|
|
1037
|
+
fileName: '',
|
|
1038
|
+
error: parsed.message
|
|
1039
|
+
}];
|
|
1040
|
+
return _context2.a(2);
|
|
1041
|
+
case 11:
|
|
1042
|
+
result = parsed.data;
|
|
871
1043
|
if (result.sessionId && result.sessionId !== _this.getSessionId()) {
|
|
872
1044
|
_this.initializeSession(result.sessionId);
|
|
873
1045
|
}
|
|
@@ -879,10 +1051,10 @@ window.coreAIChatManager = function () {
|
|
|
879
1051
|
if (result.failed && result.failed.length > 0) {
|
|
880
1052
|
_this.uploadErrors = result.failed;
|
|
881
1053
|
}
|
|
882
|
-
_context2.n =
|
|
1054
|
+
_context2.n = 13;
|
|
883
1055
|
break;
|
|
884
|
-
case
|
|
885
|
-
_context2.p =
|
|
1056
|
+
case 12:
|
|
1057
|
+
_context2.p = 12;
|
|
886
1058
|
_t2 = _context2.v;
|
|
887
1059
|
console.error('Upload error:', _t2);
|
|
888
1060
|
_this.uploadErrors = [{
|
|
@@ -892,15 +1064,15 @@ window.coreAIChatManager = function () {
|
|
|
892
1064
|
if (_this.getSessionId()) {
|
|
893
1065
|
_this.reloadCurrentSession();
|
|
894
1066
|
}
|
|
895
|
-
case
|
|
896
|
-
_context2.p =
|
|
1067
|
+
case 13:
|
|
1068
|
+
_context2.p = 13;
|
|
897
1069
|
_this.isUploading = false;
|
|
898
1070
|
_this.renderDocumentBar();
|
|
899
|
-
return _context2.f(
|
|
900
|
-
case
|
|
1071
|
+
return _context2.f(13);
|
|
1072
|
+
case 14:
|
|
901
1073
|
return _context2.a(2);
|
|
902
1074
|
}
|
|
903
|
-
}, _callee2, null, [[6,
|
|
1075
|
+
}, _callee2, null, [[6, 12, 13, 14], [1, 3]]);
|
|
904
1076
|
}))));
|
|
905
1077
|
}
|
|
906
1078
|
}, _callee3);
|
|
@@ -919,7 +1091,7 @@ window.coreAIChatManager = function () {
|
|
|
919
1091
|
return _context5.a(2);
|
|
920
1092
|
case 1:
|
|
921
1093
|
return _context5.a(2, _this2.queueDocumentOperation(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
922
|
-
var sessionId, response, result, idx, errorText, removeError, _t3;
|
|
1094
|
+
var sessionId, response, secondParsed, result, idx, errorText, removeError, _t3;
|
|
923
1095
|
return _regenerator().w(function (_context4) {
|
|
924
1096
|
while (1) switch (_context4.p = _context4.n) {
|
|
925
1097
|
case 0:
|
|
@@ -939,13 +1111,24 @@ window.coreAIChatManager = function () {
|
|
|
939
1111
|
case 1:
|
|
940
1112
|
response = _context4.v;
|
|
941
1113
|
if (!response.ok) {
|
|
942
|
-
_context4.n =
|
|
1114
|
+
_context4.n = 4;
|
|
943
1115
|
break;
|
|
944
1116
|
}
|
|
945
1117
|
_context4.n = 2;
|
|
946
|
-
return response.
|
|
1118
|
+
return readJsonResponse(response, 'The request could not be completed.');
|
|
947
1119
|
case 2:
|
|
948
|
-
|
|
1120
|
+
secondParsed = _context4.v;
|
|
1121
|
+
if (secondParsed.ok) {
|
|
1122
|
+
_context4.n = 3;
|
|
1123
|
+
break;
|
|
1124
|
+
}
|
|
1125
|
+
console.error('Response was not JSON.', {
|
|
1126
|
+
status: response.status,
|
|
1127
|
+
redirected: response.redirected
|
|
1128
|
+
});
|
|
1129
|
+
return _context4.a(2);
|
|
1130
|
+
case 3:
|
|
1131
|
+
result = secondParsed.data;
|
|
949
1132
|
if (Array.isArray(result.documents)) {
|
|
950
1133
|
_this2.documents = result.documents;
|
|
951
1134
|
} else {
|
|
@@ -954,12 +1137,12 @@ window.coreAIChatManager = function () {
|
|
|
954
1137
|
_this2.documents.splice(idx, 1);
|
|
955
1138
|
}
|
|
956
1139
|
}
|
|
957
|
-
_context4.n =
|
|
1140
|
+
_context4.n = 6;
|
|
958
1141
|
break;
|
|
959
|
-
case 3:
|
|
960
|
-
_context4.n = 4;
|
|
961
|
-
return response.text();
|
|
962
1142
|
case 4:
|
|
1143
|
+
_context4.n = 5;
|
|
1144
|
+
return response.text();
|
|
1145
|
+
case 5:
|
|
963
1146
|
errorText = _context4.v;
|
|
964
1147
|
removeError = _this2.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');
|
|
965
1148
|
console.error('Failed to remove document:', response.status, errorText);
|
|
@@ -971,11 +1154,11 @@ window.coreAIChatManager = function () {
|
|
|
971
1154
|
_this2.reloadCurrentSession();
|
|
972
1155
|
}
|
|
973
1156
|
_this2.renderDocumentBar();
|
|
974
|
-
case 5:
|
|
975
|
-
_context4.n = 7;
|
|
976
|
-
break;
|
|
977
1157
|
case 6:
|
|
978
|
-
_context4.
|
|
1158
|
+
_context4.n = 8;
|
|
1159
|
+
break;
|
|
1160
|
+
case 7:
|
|
1161
|
+
_context4.p = 7;
|
|
979
1162
|
_t3 = _context4.v;
|
|
980
1163
|
console.error('Remove document error:', _t3);
|
|
981
1164
|
_this2.uploadErrors = [{
|
|
@@ -986,10 +1169,10 @@ window.coreAIChatManager = function () {
|
|
|
986
1169
|
_this2.reloadCurrentSession();
|
|
987
1170
|
}
|
|
988
1171
|
_this2.renderDocumentBar();
|
|
989
|
-
case
|
|
1172
|
+
case 8:
|
|
990
1173
|
return _context4.a(2);
|
|
991
1174
|
}
|
|
992
|
-
}, _callee4, null, [[0,
|
|
1175
|
+
}, _callee4, null, [[0, 7]]);
|
|
993
1176
|
}))));
|
|
994
1177
|
}
|
|
995
1178
|
}, _callee5);
|
|
@@ -1023,11 +1206,19 @@ window.coreAIChatManager = function () {
|
|
|
1023
1206
|
var failedItem = this.uploadErrors[m];
|
|
1024
1207
|
var failedName = failedItem.fileName || 'File';
|
|
1025
1208
|
var errorMsg = failedItem.error || 'Upload failed';
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
html += '
|
|
1209
|
+
// The reason is shown, not hidden behind a tooltip. A pill reading "quarterly-report-2..."
|
|
1210
|
+
// tells a reader their upload failed and nothing about why, and a title attribute is
|
|
1211
|
+
// unreachable on a touch device -- so the one sentence that tells them what to do next
|
|
1212
|
+
// was the one thing the widget would not display.
|
|
1213
|
+
html += '<span class="alert alert-danger d-flex align-items-start gap-2 w-100 mb-1 py-1 px-2" role="alert" style="font-size: 0.8rem;">';
|
|
1214
|
+
html += '<i class="fa-solid fa-circle-exclamation mt-1" style="font-size: 0.7rem;"></i>';
|
|
1215
|
+
html += '<span class="flex-grow-1">';
|
|
1216
|
+
if (failedItem.fileName) {
|
|
1217
|
+
html += '<strong>' + this.escapeHtml(failedItem.fileName) + '</strong>: ';
|
|
1218
|
+
}
|
|
1219
|
+
html += this.escapeHtml(errorMsg);
|
|
1220
|
+
html += '</span>';
|
|
1221
|
+
html += '<button type="button" class="btn-close btn-close-sm" style="font-size: 0.5rem;" data-error-index="' + m + '" aria-label="Dismiss"></button>';
|
|
1031
1222
|
html += '</span>';
|
|
1032
1223
|
}
|
|
1033
1224
|
if (this.isUploading) {
|
|
@@ -1187,7 +1378,7 @@ window.coreAIChatManager = function () {
|
|
|
1187
1378
|
((_data$messages = data.messages) !== null && _data$messages !== void 0 ? _data$messages : []).forEach(function (msg) {
|
|
1188
1379
|
_this3.addMessage(msg);
|
|
1189
1380
|
_this3.$nextTick(function () {
|
|
1190
|
-
|
|
1381
|
+
renderMessageMedia(msg);
|
|
1191
1382
|
});
|
|
1192
1383
|
});
|
|
1193
1384
|
|
|
@@ -1380,7 +1571,7 @@ window.coreAIChatManager = function () {
|
|
|
1380
1571
|
msg.references = normalizeReferences(Object.assign({}, msg.references || {}, references || {}));
|
|
1381
1572
|
updateMessagePresentation(msg, msg.references);
|
|
1382
1573
|
_this3.$nextTick(function () {
|
|
1383
|
-
|
|
1574
|
+
renderMessageMedia(msg);
|
|
1384
1575
|
_this3.scrollToBottom();
|
|
1385
1576
|
});
|
|
1386
1577
|
}
|
|
@@ -1569,7 +1760,7 @@ window.coreAIChatManager = function () {
|
|
|
1569
1760
|
this.hidePlaceholder();
|
|
1570
1761
|
this.$nextTick(function () {
|
|
1571
1762
|
// Render any pending charts once the DOM is updated
|
|
1572
|
-
|
|
1763
|
+
renderMessageMedia(message);
|
|
1573
1764
|
_this6.scrollToBottom();
|
|
1574
1765
|
});
|
|
1575
1766
|
},
|
|
@@ -1895,7 +2086,7 @@ window.coreAIChatManager = function () {
|
|
|
1895
2086
|
updateMessagePresentation(message, references);
|
|
1896
2087
|
_this9.messages[messageIndex] = message;
|
|
1897
2088
|
_this9.$nextTick(function () {
|
|
1898
|
-
|
|
2089
|
+
renderMessageMedia(message);
|
|
1899
2090
|
_this9.scrollToBottom();
|
|
1900
2091
|
});
|
|
1901
2092
|
},
|
|
@@ -1963,7 +2154,7 @@ window.coreAIChatManager = function () {
|
|
|
1963
2154
|
updateMessagePresentation(message, references);
|
|
1964
2155
|
this.messages[messageIndex] = message;
|
|
1965
2156
|
this.$nextTick(function () {
|
|
1966
|
-
|
|
2157
|
+
renderMessageMedia(message);
|
|
1967
2158
|
_this0.scrollToBottom();
|
|
1968
2159
|
});
|
|
1969
2160
|
}
|
|
@@ -2114,18 +2305,18 @@ window.coreAIChatManager = function () {
|
|
|
2114
2305
|
}, 0);
|
|
2115
2306
|
var combined = new Uint8Array(totalLength);
|
|
2116
2307
|
var offset = 0;
|
|
2117
|
-
var
|
|
2118
|
-
|
|
2308
|
+
var _iterator8 = _createForOfIteratorHelper(this.audioChunks),
|
|
2309
|
+
_step8;
|
|
2119
2310
|
try {
|
|
2120
|
-
for (
|
|
2121
|
-
var chunk =
|
|
2311
|
+
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
2312
|
+
var chunk = _step8.value;
|
|
2122
2313
|
combined.set(chunk, offset);
|
|
2123
2314
|
offset += chunk.length;
|
|
2124
2315
|
}
|
|
2125
2316
|
} catch (err) {
|
|
2126
|
-
|
|
2317
|
+
_iterator8.e(err);
|
|
2127
2318
|
} finally {
|
|
2128
|
-
|
|
2319
|
+
_iterator8.f();
|
|
2129
2320
|
}
|
|
2130
2321
|
this.audioChunks = [];
|
|
2131
2322
|
var blob = new Blob([combined], {
|