@cognitiondesk/widget 1.1.0 β 1.2.1
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/README.md +212 -44
- package/dist/react.es.js +171 -133
- package/dist/react.umd.cjs +4 -4
- package/dist/widget.es.js +106 -80
- package/dist/widget.umd.cjs +4 -4
- package/package.json +1 -1
- package/src/react.jsx +12 -0
- package/src/widget.js +57 -5
package/dist/react.es.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { forwardRef as
|
|
3
|
-
const
|
|
1
|
+
import { jsx as S } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as N, useRef as M, useImperativeHandle as I, useEffect as C } from "react";
|
|
3
|
+
const P = "https://mounaji-backendv3.onrender.com", B = `
|
|
4
4
|
:host {
|
|
5
5
|
all: initial;
|
|
6
6
|
font-family: system-ui, sans-serif;
|
|
@@ -246,33 +246,42 @@ const L = "https://mounaji-backendv3.onrender.com", N = `
|
|
|
246
246
|
font-size: 16px;
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
|
-
`,
|
|
249
|
+
`, x = {
|
|
250
250
|
chat: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',
|
|
251
251
|
close: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',
|
|
252
252
|
send: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>'
|
|
253
253
|
};
|
|
254
|
-
function
|
|
254
|
+
function z() {
|
|
255
255
|
return "cd_" + Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
256
256
|
}
|
|
257
|
-
let
|
|
258
|
-
constructor(
|
|
259
|
-
|
|
257
|
+
let D = class {
|
|
258
|
+
constructor(t = {}) {
|
|
259
|
+
var e, a, s, r, n;
|
|
260
|
+
if (!t.apiKey) throw new Error("[CognitionDesk] apiKey is required");
|
|
260
261
|
this._cfg = {
|
|
261
|
-
apiKey:
|
|
262
|
-
widgetId:
|
|
263
|
-
assistantId:
|
|
264
|
-
backendUrl:
|
|
265
|
-
primaryColor:
|
|
266
|
-
theme:
|
|
262
|
+
apiKey: t.apiKey,
|
|
263
|
+
widgetId: t.widgetId || null,
|
|
264
|
+
assistantId: t.assistantId || null,
|
|
265
|
+
backendUrl: t.backendUrl || P,
|
|
266
|
+
primaryColor: t.primaryColor || "#2563eb",
|
|
267
|
+
theme: t.theme || "light",
|
|
267
268
|
// 'light' | 'dark' | 'auto'
|
|
268
|
-
botName:
|
|
269
|
-
botEmoji:
|
|
270
|
-
welcomeMessage:
|
|
271
|
-
placeholder:
|
|
272
|
-
position:
|
|
273
|
-
streaming:
|
|
269
|
+
botName: t.botName || "AI Assistant",
|
|
270
|
+
botEmoji: t.botEmoji || "π€",
|
|
271
|
+
welcomeMessage: t.welcomeMessage || "Hello! How can I help you today?",
|
|
272
|
+
placeholder: t.placeholder || "Type a messageβ¦",
|
|
273
|
+
position: t.position || "bottom-right",
|
|
274
|
+
streaming: t.streaming !== !1,
|
|
274
275
|
// default: true
|
|
275
|
-
|
|
276
|
+
// Rate limiting β can be overridden by inline config or merged from server config
|
|
277
|
+
rateLimiting: {
|
|
278
|
+
enabled: ((e = t.rateLimiting) == null ? void 0 : e.enabled) !== !1,
|
|
279
|
+
maxMessagesPerSession: ((a = t.rateLimiting) == null ? void 0 : a.maxMessagesPerSession) ?? 0,
|
|
280
|
+
maxMessagesPerMinute: ((s = t.rateLimiting) == null ? void 0 : s.maxMessagesPerMinute) ?? 0,
|
|
281
|
+
limitReachedMessage: ((r = t.rateLimiting) == null ? void 0 : r.limitReachedMessage) || "You've reached the message limit for this session.",
|
|
282
|
+
rateLimitMessage: ((n = t.rateLimiting) == null ? void 0 : n.rateLimitMessage) || "You're sending messages too quickly. Please wait a moment."
|
|
283
|
+
}
|
|
284
|
+
}, this._sessionId = z(), this._messageCount = 0, this._minuteCount = 0, this._minuteStart = Date.now(), this._messages = [], this._open = !1, this._loading = !1, this._container = null, this._shadow = null, this._panel = null, this._messagesEl = null, this._textarea = null, this._sendBtn = null, this._viewportHandler = null;
|
|
276
285
|
}
|
|
277
286
|
// ββ Public API ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
278
287
|
/**
|
|
@@ -280,45 +289,45 @@ let S = class {
|
|
|
280
289
|
* If `widgetId` was provided, fetches the server-side config first (async).
|
|
281
290
|
* Returns a Promise so callers can await full initialisation.
|
|
282
291
|
*/
|
|
283
|
-
mount(
|
|
284
|
-
const
|
|
285
|
-
const a =
|
|
292
|
+
mount(t) {
|
|
293
|
+
const e = () => {
|
|
294
|
+
const a = t || document.body;
|
|
286
295
|
this._container = document.createElement("div"), this._container.setAttribute("data-cognitiondesk", ""), a.appendChild(this._container), this._shadow = this._container.attachShadow({ mode: "open" });
|
|
287
296
|
const s = document.createElement("style");
|
|
288
|
-
s.textContent =
|
|
297
|
+
s.textContent = B, this._shadow.appendChild(s), this._buildDOM(), this._applyTheme(), this._syncViewportMetrics(), this._bindViewportMetrics(), this._bindEvents(), this._cfg.welcomeMessage && this._appendMessage("assistant", this._cfg.welcomeMessage, !1);
|
|
289
298
|
};
|
|
290
|
-
return this._cfg.widgetId ? this._fetchWidgetConfig().then(() =>
|
|
299
|
+
return this._cfg.widgetId ? this._fetchWidgetConfig().then(() => e()).catch(() => e()) : (e(), Promise.resolve(this));
|
|
291
300
|
}
|
|
292
301
|
/**
|
|
293
302
|
* Fetch public widget config from the platform and merge into this._cfg.
|
|
294
303
|
* Only fields not already overridden by the constructor are applied.
|
|
295
304
|
*/
|
|
296
305
|
async _fetchWidgetConfig() {
|
|
297
|
-
var
|
|
298
|
-
const
|
|
306
|
+
var e;
|
|
307
|
+
const t = `${this._cfg.backendUrl}/platforms/web-widget/public/${this._cfg.widgetId}`;
|
|
299
308
|
try {
|
|
300
|
-
const a = await fetch(
|
|
309
|
+
const a = await fetch(t);
|
|
301
310
|
if (!a.ok) return;
|
|
302
311
|
const { config: s } = await a.json();
|
|
303
312
|
if (!s) return;
|
|
304
|
-
s.botName && !this._userSet("botName") && (this._cfg.botName = s.botName), s.welcomeMessage && !this._userSet("welcomeMessage") && (this._cfg.welcomeMessage = s.welcomeMessage), s.primaryColor && !this._userSet("primaryColor") && (this._cfg.primaryColor = s.primaryColor), s.placeholder && !this._userSet("placeholder") && (this._cfg.placeholder = s.placeholder), s.assistantId && !this._cfg.assistantId && (this._cfg.assistantId = s.assistantId), (
|
|
313
|
+
s.botName && !this._userSet("botName") && (this._cfg.botName = s.botName), s.welcomeMessage && !this._userSet("welcomeMessage") && (this._cfg.welcomeMessage = s.welcomeMessage), s.primaryColor && !this._userSet("primaryColor") && (this._cfg.primaryColor = s.primaryColor), s.placeholder && !this._userSet("placeholder") && (this._cfg.placeholder = s.placeholder), s.assistantId && !this._cfg.assistantId && (this._cfg.assistantId = s.assistantId), (e = s.avatar) != null && e.value && !this._userSet("botEmoji") && (this._cfg.botEmoji = s.avatar.value), s.rateLimiting && (this._cfg.rateLimiting = { ...this._cfg.rateLimiting, ...s.rateLimiting });
|
|
305
314
|
} catch {
|
|
306
315
|
}
|
|
307
316
|
}
|
|
308
317
|
// eslint-disable-next-line no-unused-vars
|
|
309
|
-
_userSet(
|
|
318
|
+
_userSet(t) {
|
|
310
319
|
return !1;
|
|
311
320
|
}
|
|
312
321
|
unmount() {
|
|
313
322
|
this._unbindViewportMetrics(), this._container && (this._container.remove(), this._container = null);
|
|
314
323
|
}
|
|
315
324
|
open() {
|
|
316
|
-
var
|
|
317
|
-
this._open = !0, this._syncViewportMetrics(), (
|
|
325
|
+
var t, e;
|
|
326
|
+
this._open = !0, this._syncViewportMetrics(), (t = this._panel) == null || t.classList.add("open"), (e = this._textarea) == null || e.focus();
|
|
318
327
|
}
|
|
319
328
|
close() {
|
|
320
|
-
var
|
|
321
|
-
this._open = !1, (
|
|
329
|
+
var t;
|
|
330
|
+
this._open = !1, (t = this._panel) == null || t.classList.remove("open");
|
|
322
331
|
}
|
|
323
332
|
toggle() {
|
|
324
333
|
this._open ? this.close() : this.open();
|
|
@@ -328,10 +337,10 @@ let S = class {
|
|
|
328
337
|
}
|
|
329
338
|
// ββ DOM βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
330
339
|
_buildDOM() {
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
const
|
|
334
|
-
|
|
340
|
+
const t = document.createElement("div");
|
|
341
|
+
t.className = "cd-root";
|
|
342
|
+
const e = document.createElement("button");
|
|
343
|
+
e.className = "cd-widget-btn", e.innerHTML = x.chat, e.setAttribute("aria-label", "Open chat"), e.style.setProperty("--cd-primary", this._cfg.primaryColor), this._toggleBtn = e;
|
|
335
344
|
const a = document.createElement("div");
|
|
336
345
|
a.className = "cd-panel", this._panel = a;
|
|
337
346
|
const s = document.createElement("div");
|
|
@@ -344,27 +353,27 @@ let S = class {
|
|
|
344
353
|
</div>
|
|
345
354
|
</div>
|
|
346
355
|
`;
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
const r = document.createElement("div");
|
|
350
|
-
r.className = "cd-messages", r.setAttribute("role", "log"), r.setAttribute("aria-live", "polite"), this._messagesEl = r;
|
|
356
|
+
const r = document.createElement("button");
|
|
357
|
+
r.className = "cd-close-btn", r.innerHTML = x.close, r.setAttribute("aria-label", "Close chat"), s.appendChild(r), this._closeBtn = r;
|
|
351
358
|
const n = document.createElement("div");
|
|
352
|
-
n.className = "cd-
|
|
353
|
-
const d = document.createElement("
|
|
354
|
-
d.className = "cd-
|
|
359
|
+
n.className = "cd-messages", n.setAttribute("role", "log"), n.setAttribute("aria-live", "polite"), this._messagesEl = n;
|
|
360
|
+
const d = document.createElement("div");
|
|
361
|
+
d.className = "cd-input-area";
|
|
362
|
+
const o = document.createElement("textarea");
|
|
363
|
+
o.className = "cd-textarea", o.rows = 1, o.placeholder = this._cfg.placeholder, this._textarea = o;
|
|
355
364
|
const c = document.createElement("button");
|
|
356
|
-
c.className = "cd-send-btn", c.innerHTML =
|
|
365
|
+
c.className = "cd-send-btn", c.innerHTML = x.send, c.setAttribute("aria-label", "Send"), this._sendBtn = c, d.appendChild(o), d.appendChild(c);
|
|
357
366
|
const l = document.createElement("div");
|
|
358
|
-
l.className = "cd-powered", l.innerHTML = 'Powered by <a href="https://cognitiondesk.com" target="_blank" rel="noopener">CognitionDesk</a>', a.appendChild(s), a.appendChild(
|
|
367
|
+
l.className = "cd-powered", l.innerHTML = 'Powered by <a href="https://cognitiondesk.com" target="_blank" rel="noopener">CognitionDesk</a>', a.appendChild(s), a.appendChild(n), a.appendChild(d), a.appendChild(l), t.appendChild(e), t.appendChild(a), this._shadow.appendChild(t), this._root = t;
|
|
359
368
|
}
|
|
360
369
|
_applyTheme() {
|
|
361
|
-
var
|
|
362
|
-
(this._cfg.theme === "auto" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : this._cfg.theme) === "dark" && ((
|
|
370
|
+
var e, a, s;
|
|
371
|
+
(this._cfg.theme === "auto" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : this._cfg.theme) === "dark" && ((e = this._root) == null || e.classList.add("cd-dark")), (a = this._root) == null || a.style.setProperty("--cd-primary", this._cfg.primaryColor), (s = this._panel) == null || s.style.setProperty("--cd-primary", this._cfg.primaryColor);
|
|
363
372
|
}
|
|
364
373
|
// ββ Events ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
365
374
|
_bindEvents() {
|
|
366
|
-
this._toggleBtn.addEventListener("click", () => this.toggle()), this._closeBtn.addEventListener("click", () => this.close()), this._sendBtn.addEventListener("click", () => this._sendMessage()), this._textarea.addEventListener("keydown", (
|
|
367
|
-
|
|
375
|
+
this._toggleBtn.addEventListener("click", () => this.toggle()), this._closeBtn.addEventListener("click", () => this.close()), this._sendBtn.addEventListener("click", () => this._sendMessage()), this._textarea.addEventListener("keydown", (t) => {
|
|
376
|
+
t.key === "Enter" && !t.shiftKey && (t.preventDefault(), this._sendMessage());
|
|
368
377
|
}), this._textarea.addEventListener("input", () => {
|
|
369
378
|
this._textarea.style.height = "auto", this._textarea.style.height = Math.min(this._textarea.scrollHeight, 120) + "px";
|
|
370
379
|
}), this._textarea.addEventListener("focus", () => {
|
|
@@ -378,28 +387,45 @@ let S = class {
|
|
|
378
387
|
this._viewportHandler && (window.removeEventListener("resize", this._viewportHandler), window.removeEventListener("orientationchange", this._viewportHandler), window.visualViewport && (window.visualViewport.removeEventListener("resize", this._viewportHandler), window.visualViewport.removeEventListener("scroll", this._viewportHandler)), this._viewportHandler = null);
|
|
379
388
|
}
|
|
380
389
|
_syncViewportMetrics() {
|
|
381
|
-
const
|
|
382
|
-
if (!
|
|
383
|
-
const
|
|
384
|
-
|
|
390
|
+
const t = this._root || this._container;
|
|
391
|
+
if (!t) return;
|
|
392
|
+
const e = window.visualViewport, a = e ? e.height : window.innerHeight;
|
|
393
|
+
t.style.setProperty("--cd-viewport-height", `${Math.round(a)}px`);
|
|
385
394
|
}
|
|
386
395
|
// ββ Chat ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
387
396
|
async _sendMessage() {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
}
|
|
398
|
-
} catch (t) {
|
|
399
|
-
this._appendMessage("error", "Sorry, something went wrong. Please try again.", !1), console.error("[CognitionDesk]", t);
|
|
400
|
-
} finally {
|
|
401
|
-
this._loading = !1, this._sendBtn.disabled = !1, this._textarea.focus();
|
|
397
|
+
var a;
|
|
398
|
+
const t = this._textarea.value.trim();
|
|
399
|
+
if (!t || this._loading) return;
|
|
400
|
+
const e = this._cfg.rateLimiting;
|
|
401
|
+
if (e != null && e.enabled) {
|
|
402
|
+
const s = Date.now();
|
|
403
|
+
if (s - this._minuteStart >= 6e4 && (this._minuteCount = 0, this._minuteStart = s), e.maxMessagesPerSession > 0 && this._messageCount >= e.maxMessagesPerSession) {
|
|
404
|
+
this._appendMessage("error", e.limitReachedMessage, !1), this._textarea.disabled = !0, this._sendBtn.disabled = !0;
|
|
405
|
+
return;
|
|
402
406
|
}
|
|
407
|
+
if (e.maxMessagesPerMinute > 0 && this._minuteCount >= e.maxMessagesPerMinute) {
|
|
408
|
+
this._appendMessage("error", e.rateLimitMessage, !1);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
this._textarea.value = "", this._textarea.style.height = "auto", this._loading = !0, this._sendBtn.disabled = !0, this._messages.push({ role: "user", content: t }), this._appendMessage("user", t, !1), this._messageCount += 1, this._minuteCount += 1;
|
|
413
|
+
try {
|
|
414
|
+
if (this._cfg.streaming)
|
|
415
|
+
await this._callApiStream();
|
|
416
|
+
else {
|
|
417
|
+
const s = this._showTyping(), r = await this._callApi();
|
|
418
|
+
this._removeTyping(s), this._messages.push({ role: "assistant", content: r }), this._appendMessage("assistant", r, !0);
|
|
419
|
+
}
|
|
420
|
+
} catch (s) {
|
|
421
|
+
if (s.status === 429 || (a = s.message) != null && a.includes("429")) {
|
|
422
|
+
const r = s.rateLimitMessage || (e == null ? void 0 : e.rateLimitMessage) || "You're sending messages too quickly. Please wait a moment.";
|
|
423
|
+
this._appendMessage("error", r, !1);
|
|
424
|
+
} else
|
|
425
|
+
this._appendMessage("error", "Sorry, something went wrong. Please try again.", !1);
|
|
426
|
+
console.error("[CognitionDesk]", s);
|
|
427
|
+
} finally {
|
|
428
|
+
this._loading = !1, (e == null ? void 0 : e.maxMessagesPerSession) > 0 && this._messageCount >= e.maxMessagesPerSession || (this._sendBtn.disabled = !1), this._textarea.focus();
|
|
403
429
|
}
|
|
404
430
|
}
|
|
405
431
|
_buildRequestBody() {
|
|
@@ -416,107 +442,112 @@ let S = class {
|
|
|
416
442
|
}
|
|
417
443
|
/** Streaming path β uses SSE endpoint */
|
|
418
444
|
async _callApiStream() {
|
|
419
|
-
const
|
|
445
|
+
const t = `${this._cfg.backendUrl}/chat-apiKeyAuth/stream`, e = await fetch(t, {
|
|
420
446
|
method: "POST",
|
|
421
447
|
headers: { "Content-Type": "application/json", "x-api-key": this._cfg.apiKey },
|
|
422
448
|
body: JSON.stringify({ ...this._buildRequestBody(), stream: !0 })
|
|
423
449
|
});
|
|
424
|
-
if (!
|
|
425
|
-
const
|
|
426
|
-
throw
|
|
450
|
+
if (!e.ok) {
|
|
451
|
+
const o = await e.json().catch(() => ({})), c = new Error(o.message || `HTTP ${e.status}`);
|
|
452
|
+
throw c.status = e.status, c.rateLimitMessage = o.message, c;
|
|
427
453
|
}
|
|
428
454
|
const a = document.createElement("div");
|
|
429
455
|
a.className = "cd-msg assistant", a.innerHTML = '<div class="cd-typing"><span></span><span></span><span></span></div>', this._messagesEl.appendChild(a), this._scrollToBottom();
|
|
430
|
-
const s =
|
|
431
|
-
let
|
|
456
|
+
const s = e.body.getReader(), r = new TextDecoder();
|
|
457
|
+
let n = "", d = !1;
|
|
432
458
|
try {
|
|
433
459
|
for (; ; ) {
|
|
434
|
-
const { done:
|
|
435
|
-
if (
|
|
436
|
-
const l =
|
|
460
|
+
const { done: o, value: c } = await s.read();
|
|
461
|
+
if (o) break;
|
|
462
|
+
const l = r.decode(c, { stream: !0 });
|
|
437
463
|
for (const g of l.split(`
|
|
438
464
|
`)) {
|
|
439
465
|
if (!g.startsWith("data: ")) continue;
|
|
440
|
-
const
|
|
441
|
-
if (
|
|
466
|
+
const m = g.slice(6).trim();
|
|
467
|
+
if (m === "[DONE]") break;
|
|
442
468
|
let h;
|
|
443
469
|
try {
|
|
444
|
-
h = JSON.parse(
|
|
470
|
+
h = JSON.parse(m);
|
|
445
471
|
} catch {
|
|
446
472
|
continue;
|
|
447
473
|
}
|
|
448
|
-
h.type === "content" && h.data && (
|
|
474
|
+
h.type === "content" && h.data && (d || (a.innerHTML = "", d = !0), n += h.data, a.innerHTML = this._renderMarkdown(n), this._scrollToBottom());
|
|
449
475
|
}
|
|
450
476
|
}
|
|
451
477
|
} finally {
|
|
452
478
|
s.releaseLock();
|
|
453
479
|
}
|
|
454
|
-
|
|
480
|
+
d || (a.innerHTML = this._renderMarkdown("No response")), n && this._messages.push({ role: "assistant", content: n });
|
|
455
481
|
}
|
|
456
482
|
/** Non-streaming fallback path */
|
|
457
483
|
async _callApi() {
|
|
458
|
-
var s,
|
|
459
|
-
const
|
|
484
|
+
var s, r, n;
|
|
485
|
+
const t = `${this._cfg.backendUrl}/chat-apiKeyAuth/chat`, e = await fetch(t, {
|
|
460
486
|
method: "POST",
|
|
461
487
|
headers: { "Content-Type": "application/json", "x-api-key": this._cfg.apiKey },
|
|
462
488
|
body: JSON.stringify(this._buildRequestBody())
|
|
463
489
|
});
|
|
464
|
-
if (!
|
|
465
|
-
const
|
|
466
|
-
throw
|
|
490
|
+
if (!e.ok) {
|
|
491
|
+
const d = await e.json().catch(() => ({})), o = new Error(d.message || `HTTP ${e.status}`);
|
|
492
|
+
throw o.status = e.status, o.rateLimitMessage = d.message, o;
|
|
467
493
|
}
|
|
468
|
-
const a = await
|
|
469
|
-
return a.response || a.message || a.content || ((
|
|
494
|
+
const a = await e.json();
|
|
495
|
+
return a.response || a.message || a.content || ((n = (r = (s = a.choices) == null ? void 0 : s[0]) == null ? void 0 : r.message) == null ? void 0 : n.content) || "No response";
|
|
470
496
|
}
|
|
471
497
|
// ββ DOM helpers βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
472
|
-
_appendMessage(
|
|
498
|
+
_appendMessage(t, e, a = !0) {
|
|
473
499
|
const s = document.createElement("div");
|
|
474
|
-
s.className = `cd-msg ${
|
|
500
|
+
s.className = `cd-msg ${t}`, a && t !== "user" ? s.innerHTML = this._renderMarkdown(e) : s.textContent = e, this._messagesEl.appendChild(s), this._scrollToBottom();
|
|
475
501
|
}
|
|
476
502
|
/** Minimal, safe markdown β HTML renderer (no dependencies). */
|
|
477
|
-
_renderMarkdown(
|
|
478
|
-
if (!
|
|
479
|
-
let
|
|
480
|
-
return
|
|
503
|
+
_renderMarkdown(t) {
|
|
504
|
+
if (!t) return "";
|
|
505
|
+
let e = this._escHtml(t);
|
|
506
|
+
return e = e.replace(
|
|
481
507
|
/```[\w]*\n?([\s\S]*?)```/g,
|
|
482
508
|
(a, s) => `<pre style="background:#0f172a;color:#e2e8f0;padding:10px;border-radius:6px;font-size:12px;overflow-x:auto;margin:6px 0;white-space:pre-wrap">${s.trim()}</pre>`
|
|
483
|
-
),
|
|
509
|
+
), e = e.replace(/`([^`]+)`/g, '<code style="background:rgba(0,0,0,.08);padding:1px 5px;border-radius:4px;font-size:.9em">$1</code>'), e = e.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>"), e = e.replace(/__([^_]+)__/g, "<strong>$1</strong>"), e = e.replace(/\*([^*]+)\*/g, "<em>$1</em>"), e = e.replace(/_([^_]+)_/g, "<em>$1</em>"), e = e.replace(
|
|
484
510
|
/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g,
|
|
485
511
|
'<a href="$2" target="_blank" rel="noopener" style="color:var(--cd-primary,#2563eb)">$1</a>'
|
|
486
|
-
),
|
|
512
|
+
), e = e.replace(/\n/g, "<br>"), e;
|
|
487
513
|
}
|
|
488
514
|
_showTyping() {
|
|
489
|
-
const
|
|
490
|
-
return
|
|
515
|
+
const t = document.createElement("div");
|
|
516
|
+
return t.className = "cd-msg assistant", t.innerHTML = '<div class="cd-typing"><span></span><span></span><span></span></div>', this._messagesEl.appendChild(t), this._scrollToBottom(), t;
|
|
491
517
|
}
|
|
492
|
-
_removeTyping(
|
|
493
|
-
|
|
518
|
+
_removeTyping(t) {
|
|
519
|
+
t == null || t.remove();
|
|
494
520
|
}
|
|
495
521
|
_scrollToBottom() {
|
|
496
522
|
this._messagesEl && (this._messagesEl.scrollTop = this._messagesEl.scrollHeight);
|
|
497
523
|
}
|
|
498
|
-
_escHtml(
|
|
499
|
-
return String(
|
|
524
|
+
_escHtml(t) {
|
|
525
|
+
return String(t).replace(/[&<>"']/g, (e) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[e]);
|
|
500
526
|
}
|
|
501
527
|
};
|
|
502
|
-
const
|
|
528
|
+
const V = N(function(t, e) {
|
|
503
529
|
const {
|
|
504
530
|
apiKey: a,
|
|
505
531
|
widgetId: s,
|
|
506
|
-
assistantId:
|
|
507
|
-
theme:
|
|
508
|
-
primaryColor:
|
|
509
|
-
botName:
|
|
532
|
+
assistantId: r,
|
|
533
|
+
theme: n = "light",
|
|
534
|
+
primaryColor: d = "#2563eb",
|
|
535
|
+
botName: o = "AI Assistant",
|
|
510
536
|
botEmoji: c = "π€",
|
|
511
537
|
welcomeMessage: l = "Hello! How can I help you today?",
|
|
512
538
|
placeholder: g = "Type a messageβ¦",
|
|
513
|
-
defaultOpen:
|
|
539
|
+
defaultOpen: m = !1,
|
|
514
540
|
streaming: h = !0,
|
|
515
|
-
backendUrl:
|
|
516
|
-
|
|
541
|
+
backendUrl: w,
|
|
542
|
+
// Rate limiting β 0 means unlimited
|
|
543
|
+
maxMessagesPerSession: L = 0,
|
|
544
|
+
maxMessagesPerMinute: H = 0,
|
|
545
|
+
limitReachedMessage: v,
|
|
546
|
+
rateLimitMessage: y,
|
|
547
|
+
onOpen: f,
|
|
517
548
|
onClose: u
|
|
518
|
-
} =
|
|
519
|
-
return
|
|
549
|
+
} = t, p = M(null), k = M(null);
|
|
550
|
+
return I(e, () => ({
|
|
520
551
|
open: () => {
|
|
521
552
|
var i;
|
|
522
553
|
return (i = p.current) == null ? void 0 : i.open();
|
|
@@ -533,44 +564,51 @@ const D = H(function(e, t) {
|
|
|
533
564
|
var i;
|
|
534
565
|
return (i = p.current) == null ? void 0 : i.clearHistory();
|
|
535
566
|
}
|
|
536
|
-
}), []),
|
|
567
|
+
}), []), C(() => {
|
|
537
568
|
if (!a) {
|
|
538
569
|
console.error("[CognitionDesk] apiKey prop is required");
|
|
539
570
|
return;
|
|
540
571
|
}
|
|
541
|
-
const i = new
|
|
572
|
+
const i = new D({
|
|
542
573
|
apiKey: a,
|
|
543
574
|
widgetId: s,
|
|
544
|
-
assistantId:
|
|
545
|
-
theme:
|
|
546
|
-
primaryColor:
|
|
547
|
-
botName:
|
|
575
|
+
assistantId: r,
|
|
576
|
+
theme: n,
|
|
577
|
+
primaryColor: d,
|
|
578
|
+
botName: o,
|
|
548
579
|
botEmoji: c,
|
|
549
580
|
welcomeMessage: l,
|
|
550
581
|
placeholder: g,
|
|
551
582
|
streaming: h,
|
|
552
|
-
...
|
|
583
|
+
...w ? { backendUrl: w } : {},
|
|
584
|
+
rateLimiting: {
|
|
585
|
+
enabled: !0,
|
|
586
|
+
maxMessagesPerSession: L,
|
|
587
|
+
maxMessagesPerMinute: H,
|
|
588
|
+
...v ? { limitReachedMessage: v } : {},
|
|
589
|
+
...y ? { rateLimitMessage: y } : {}
|
|
590
|
+
}
|
|
553
591
|
});
|
|
554
|
-
if (
|
|
555
|
-
const _ = i.open.bind(i),
|
|
592
|
+
if (f || u) {
|
|
593
|
+
const _ = i.open.bind(i), T = i.close.bind(i);
|
|
556
594
|
i.open = (...b) => {
|
|
557
|
-
_(...b),
|
|
595
|
+
_(...b), f == null || f();
|
|
558
596
|
}, i.close = (...b) => {
|
|
559
|
-
|
|
597
|
+
T(...b), u == null || u();
|
|
560
598
|
};
|
|
561
599
|
}
|
|
562
|
-
return Promise.resolve(i.mount(
|
|
563
|
-
p.current = i,
|
|
600
|
+
return Promise.resolve(i.mount(k.current)).then(() => {
|
|
601
|
+
p.current = i, m && i.open();
|
|
564
602
|
}), () => {
|
|
565
603
|
i.unmount(), p.current = null;
|
|
566
604
|
};
|
|
567
|
-
}, [a, s,
|
|
605
|
+
}, [a, s, r]), C(() => {
|
|
568
606
|
var _;
|
|
569
607
|
const i = p.current;
|
|
570
|
-
i && (i._cfg.theme =
|
|
571
|
-
}, [
|
|
608
|
+
i && (i._cfg.theme = n, i._cfg.primaryColor = d, (_ = i._applyTheme) == null || _.call(i));
|
|
609
|
+
}, [n, d]), /* @__PURE__ */ S("div", { ref: k, "data-cognitiondesk-root": "" });
|
|
572
610
|
});
|
|
573
611
|
export {
|
|
574
|
-
|
|
575
|
-
|
|
612
|
+
V as CognitionDeskWidget,
|
|
613
|
+
D as CognitionDeskWidgetCore
|
|
576
614
|
};
|
package/dist/react.umd.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(l,f){typeof exports=="object"&&typeof module<"u"?f(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],f):(l=typeof globalThis<"u"?globalThis:l||self,f(l.CognitionDeskWidgetReact={},l.jsxRuntime,l.React))})(this,function(l,f,g){"use strict";const H="https://mounaji-backendv3.onrender.com",T=`
|
|
2
2
|
:host {
|
|
3
3
|
all: initial;
|
|
4
4
|
font-family: system-ui, sans-serif;
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
font-size: 16px;
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
-
`,v={chat:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',close:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',send:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>'};function
|
|
247
|
+
`,v={chat:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',close:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',send:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>'};function S(){return"cd_"+Math.random().toString(36).slice(2)+Date.now().toString(36)}let k=class{constructor(t={}){var e,a,s,r,n;if(!t.apiKey)throw new Error("[CognitionDesk] apiKey is required");this._cfg={apiKey:t.apiKey,widgetId:t.widgetId||null,assistantId:t.assistantId||null,backendUrl:t.backendUrl||H,primaryColor:t.primaryColor||"#2563eb",theme:t.theme||"light",botName:t.botName||"AI Assistant",botEmoji:t.botEmoji||"π€",welcomeMessage:t.welcomeMessage||"Hello! How can I help you today?",placeholder:t.placeholder||"Type a messageβ¦",position:t.position||"bottom-right",streaming:t.streaming!==!1,rateLimiting:{enabled:((e=t.rateLimiting)==null?void 0:e.enabled)!==!1,maxMessagesPerSession:((a=t.rateLimiting)==null?void 0:a.maxMessagesPerSession)??0,maxMessagesPerMinute:((s=t.rateLimiting)==null?void 0:s.maxMessagesPerMinute)??0,limitReachedMessage:((r=t.rateLimiting)==null?void 0:r.limitReachedMessage)||"You've reached the message limit for this session.",rateLimitMessage:((n=t.rateLimiting)==null?void 0:n.rateLimitMessage)||"You're sending messages too quickly. Please wait a moment."}},this._sessionId=S(),this._messageCount=0,this._minuteCount=0,this._minuteStart=Date.now(),this._messages=[],this._open=!1,this._loading=!1,this._container=null,this._shadow=null,this._panel=null,this._messagesEl=null,this._textarea=null,this._sendBtn=null,this._viewportHandler=null}mount(t){const e=()=>{const a=t||document.body;this._container=document.createElement("div"),this._container.setAttribute("data-cognitiondesk",""),a.appendChild(this._container),this._shadow=this._container.attachShadow({mode:"open"});const s=document.createElement("style");s.textContent=T,this._shadow.appendChild(s),this._buildDOM(),this._applyTheme(),this._syncViewportMetrics(),this._bindViewportMetrics(),this._bindEvents(),this._cfg.welcomeMessage&&this._appendMessage("assistant",this._cfg.welcomeMessage,!1)};return this._cfg.widgetId?this._fetchWidgetConfig().then(()=>e()).catch(()=>e()):(e(),Promise.resolve(this))}async _fetchWidgetConfig(){var e;const t=`${this._cfg.backendUrl}/platforms/web-widget/public/${this._cfg.widgetId}`;try{const a=await fetch(t);if(!a.ok)return;const{config:s}=await a.json();if(!s)return;s.botName&&!this._userSet("botName")&&(this._cfg.botName=s.botName),s.welcomeMessage&&!this._userSet("welcomeMessage")&&(this._cfg.welcomeMessage=s.welcomeMessage),s.primaryColor&&!this._userSet("primaryColor")&&(this._cfg.primaryColor=s.primaryColor),s.placeholder&&!this._userSet("placeholder")&&(this._cfg.placeholder=s.placeholder),s.assistantId&&!this._cfg.assistantId&&(this._cfg.assistantId=s.assistantId),(e=s.avatar)!=null&&e.value&&!this._userSet("botEmoji")&&(this._cfg.botEmoji=s.avatar.value),s.rateLimiting&&(this._cfg.rateLimiting={...this._cfg.rateLimiting,...s.rateLimiting})}catch{}}_userSet(t){return!1}unmount(){this._unbindViewportMetrics(),this._container&&(this._container.remove(),this._container=null)}open(){var t,e;this._open=!0,this._syncViewportMetrics(),(t=this._panel)==null||t.classList.add("open"),(e=this._textarea)==null||e.focus()}close(){var t;this._open=!1,(t=this._panel)==null||t.classList.remove("open")}toggle(){this._open?this.close():this.open()}clearHistory(){this._messages=[],this._messagesEl&&(this._messagesEl.innerHTML=""),this._cfg.welcomeMessage&&this._appendMessage("assistant",this._cfg.welcomeMessage)}_buildDOM(){const t=document.createElement("div");t.className="cd-root";const e=document.createElement("button");e.className="cd-widget-btn",e.innerHTML=v.chat,e.setAttribute("aria-label","Open chat"),e.style.setProperty("--cd-primary",this._cfg.primaryColor),this._toggleBtn=e;const a=document.createElement("div");a.className="cd-panel",this._panel=a;const s=document.createElement("div");s.className="cd-header",s.innerHTML=`
|
|
248
248
|
<div class="cd-header-avatar">${this._cfg.botEmoji}</div>
|
|
249
249
|
<div class="cd-header-info">
|
|
250
250
|
<div class="cd-header-name">${this._escHtml(this._cfg.botName)}</div>
|
|
@@ -252,5 +252,5 @@
|
|
|
252
252
|
<span class="cd-status-dot"></span> Online
|
|
253
253
|
</div>
|
|
254
254
|
</div>
|
|
255
|
-
`;const
|
|
256
|
-
`)){if(!
|
|
255
|
+
`;const r=document.createElement("button");r.className="cd-close-btn",r.innerHTML=v.close,r.setAttribute("aria-label","Close chat"),s.appendChild(r),this._closeBtn=r;const n=document.createElement("div");n.className="cd-messages",n.setAttribute("role","log"),n.setAttribute("aria-live","polite"),this._messagesEl=n;const d=document.createElement("div");d.className="cd-input-area";const o=document.createElement("textarea");o.className="cd-textarea",o.rows=1,o.placeholder=this._cfg.placeholder,this._textarea=o;const c=document.createElement("button");c.className="cd-send-btn",c.innerHTML=v.send,c.setAttribute("aria-label","Send"),this._sendBtn=c,d.appendChild(o),d.appendChild(c);const p=document.createElement("div");p.className="cd-powered",p.innerHTML='Powered by <a href="https://cognitiondesk.com" target="_blank" rel="noopener">CognitionDesk</a>',a.appendChild(s),a.appendChild(n),a.appendChild(d),a.appendChild(p),t.appendChild(e),t.appendChild(a),this._shadow.appendChild(t),this._root=t}_applyTheme(){var e,a,s;(this._cfg.theme==="auto"?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":this._cfg.theme)==="dark"&&((e=this._root)==null||e.classList.add("cd-dark")),(a=this._root)==null||a.style.setProperty("--cd-primary",this._cfg.primaryColor),(s=this._panel)==null||s.style.setProperty("--cd-primary",this._cfg.primaryColor)}_bindEvents(){this._toggleBtn.addEventListener("click",()=>this.toggle()),this._closeBtn.addEventListener("click",()=>this.close()),this._sendBtn.addEventListener("click",()=>this._sendMessage()),this._textarea.addEventListener("keydown",t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),this._sendMessage())}),this._textarea.addEventListener("input",()=>{this._textarea.style.height="auto",this._textarea.style.height=Math.min(this._textarea.scrollHeight,120)+"px"}),this._textarea.addEventListener("focus",()=>{this._syncViewportMetrics()})}_bindViewportMetrics(){this._viewportHandler||(this._viewportHandler=()=>this._syncViewportMetrics(),window.addEventListener("resize",this._viewportHandler,{passive:!0}),window.addEventListener("orientationchange",this._viewportHandler),window.visualViewport&&(window.visualViewport.addEventListener("resize",this._viewportHandler),window.visualViewport.addEventListener("scroll",this._viewportHandler)))}_unbindViewportMetrics(){this._viewportHandler&&(window.removeEventListener("resize",this._viewportHandler),window.removeEventListener("orientationchange",this._viewportHandler),window.visualViewport&&(window.visualViewport.removeEventListener("resize",this._viewportHandler),window.visualViewport.removeEventListener("scroll",this._viewportHandler)),this._viewportHandler=null)}_syncViewportMetrics(){const t=this._root||this._container;if(!t)return;const e=window.visualViewport,a=e?e.height:window.innerHeight;t.style.setProperty("--cd-viewport-height",`${Math.round(a)}px`)}async _sendMessage(){var a;const t=this._textarea.value.trim();if(!t||this._loading)return;const e=this._cfg.rateLimiting;if(e!=null&&e.enabled){const s=Date.now();if(s-this._minuteStart>=6e4&&(this._minuteCount=0,this._minuteStart=s),e.maxMessagesPerSession>0&&this._messageCount>=e.maxMessagesPerSession){this._appendMessage("error",e.limitReachedMessage,!1),this._textarea.disabled=!0,this._sendBtn.disabled=!0;return}if(e.maxMessagesPerMinute>0&&this._minuteCount>=e.maxMessagesPerMinute){this._appendMessage("error",e.rateLimitMessage,!1);return}}this._textarea.value="",this._textarea.style.height="auto",this._loading=!0,this._sendBtn.disabled=!0,this._messages.push({role:"user",content:t}),this._appendMessage("user",t,!1),this._messageCount+=1,this._minuteCount+=1;try{if(this._cfg.streaming)await this._callApiStream();else{const s=this._showTyping(),r=await this._callApi();this._removeTyping(s),this._messages.push({role:"assistant",content:r}),this._appendMessage("assistant",r,!0)}}catch(s){if(s.status===429||(a=s.message)!=null&&a.includes("429")){const r=s.rateLimitMessage||(e==null?void 0:e.rateLimitMessage)||"You're sending messages too quickly. Please wait a moment.";this._appendMessage("error",r,!1)}else this._appendMessage("error","Sorry, something went wrong. Please try again.",!1);console.error("[CognitionDesk]",s)}finally{this._loading=!1,(e==null?void 0:e.maxMessagesPerSession)>0&&this._messageCount>=e.maxMessagesPerSession||(this._sendBtn.disabled=!1),this._textarea.focus()}}_buildRequestBody(){return{messages:this._messages,assistantId:this._cfg.assistantId||void 0,userContext:{sessionId:this._sessionId,assistantId:this._cfg.assistantId||void 0,widgetId:this._cfg.widgetId||void 0,platform:"cognitiondesk-widget"}}}async _callApiStream(){const t=`${this._cfg.backendUrl}/chat-apiKeyAuth/stream`,e=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":this._cfg.apiKey},body:JSON.stringify({...this._buildRequestBody(),stream:!0})});if(!e.ok){const o=await e.json().catch(()=>({})),c=new Error(o.message||`HTTP ${e.status}`);throw c.status=e.status,c.rateLimitMessage=o.message,c}const a=document.createElement("div");a.className="cd-msg assistant",a.innerHTML='<div class="cd-typing"><span></span><span></span><span></span></div>',this._messagesEl.appendChild(a),this._scrollToBottom();const s=e.body.getReader(),r=new TextDecoder;let n="",d=!1;try{for(;;){const{done:o,value:c}=await s.read();if(o)break;const p=r.decode(c,{stream:!0});for(const u of p.split(`
|
|
256
|
+
`)){if(!u.startsWith("data: "))continue;const _=u.slice(6).trim();if(_==="[DONE]")break;let m;try{m=JSON.parse(_)}catch{continue}m.type==="content"&&m.data&&(d||(a.innerHTML="",d=!0),n+=m.data,a.innerHTML=this._renderMarkdown(n),this._scrollToBottom())}}}finally{s.releaseLock()}d||(a.innerHTML=this._renderMarkdown("No response")),n&&this._messages.push({role:"assistant",content:n})}async _callApi(){var s,r,n;const t=`${this._cfg.backendUrl}/chat-apiKeyAuth/chat`,e=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":this._cfg.apiKey},body:JSON.stringify(this._buildRequestBody())});if(!e.ok){const d=await e.json().catch(()=>({})),o=new Error(d.message||`HTTP ${e.status}`);throw o.status=e.status,o.rateLimitMessage=d.message,o}const a=await e.json();return a.response||a.message||a.content||((n=(r=(s=a.choices)==null?void 0:s[0])==null?void 0:r.message)==null?void 0:n.content)||"No response"}_appendMessage(t,e,a=!0){const s=document.createElement("div");s.className=`cd-msg ${t}`,a&&t!=="user"?s.innerHTML=this._renderMarkdown(e):s.textContent=e,this._messagesEl.appendChild(s),this._scrollToBottom()}_renderMarkdown(t){if(!t)return"";let e=this._escHtml(t);return e=e.replace(/```[\w]*\n?([\s\S]*?)```/g,(a,s)=>`<pre style="background:#0f172a;color:#e2e8f0;padding:10px;border-radius:6px;font-size:12px;overflow-x:auto;margin:6px 0;white-space:pre-wrap">${s.trim()}</pre>`),e=e.replace(/`([^`]+)`/g,'<code style="background:rgba(0,0,0,.08);padding:1px 5px;border-radius:4px;font-size:.9em">$1</code>'),e=e.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),e=e.replace(/__([^_]+)__/g,"<strong>$1</strong>"),e=e.replace(/\*([^*]+)\*/g,"<em>$1</em>"),e=e.replace(/_([^_]+)_/g,"<em>$1</em>"),e=e.replace(/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g,'<a href="$2" target="_blank" rel="noopener" style="color:var(--cd-primary,#2563eb)">$1</a>'),e=e.replace(/\n/g,"<br>"),e}_showTyping(){const t=document.createElement("div");return t.className="cd-msg assistant",t.innerHTML='<div class="cd-typing"><span></span><span></span><span></span></div>',this._messagesEl.appendChild(t),this._scrollToBottom(),t}_removeTyping(t){t==null||t.remove()}_scrollToBottom(){this._messagesEl&&(this._messagesEl.scrollTop=this._messagesEl.scrollHeight)}_escHtml(t){return String(t).replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[e])}};const N=g.forwardRef(function(t,e){const{apiKey:a,widgetId:s,assistantId:r,theme:n="light",primaryColor:d="#2563eb",botName:o="AI Assistant",botEmoji:c="π€",welcomeMessage:p="Hello! How can I help you today?",placeholder:u="Type a messageβ¦",defaultOpen:_=!1,streaming:m=!0,backendUrl:M,maxMessagesPerSession:P=0,maxMessagesPerMinute:j=0,limitReachedMessage:C,rateLimitMessage:E,onOpen:b,onClose:x}=t,h=g.useRef(null),L=g.useRef(null);return g.useImperativeHandle(e,()=>({open:()=>{var i;return(i=h.current)==null?void 0:i.open()},close:()=>{var i;return(i=h.current)==null?void 0:i.close()},toggle:()=>{var i;return(i=h.current)==null?void 0:i.toggle()},clearHistory:()=>{var i;return(i=h.current)==null?void 0:i.clearHistory()}}),[]),g.useEffect(()=>{if(!a){console.error("[CognitionDesk] apiKey prop is required");return}const i=new k({apiKey:a,widgetId:s,assistantId:r,theme:n,primaryColor:d,botName:o,botEmoji:c,welcomeMessage:p,placeholder:u,streaming:m,...M?{backendUrl:M}:{},rateLimiting:{enabled:!0,maxMessagesPerSession:P,maxMessagesPerMinute:j,...C?{limitReachedMessage:C}:{},...E?{rateLimitMessage:E}:{}}});if(b||x){const w=i.open.bind(i),B=i.close.bind(i);i.open=(...y)=>{w(...y),b==null||b()},i.close=(...y)=>{B(...y),x==null||x()}}return Promise.resolve(i.mount(L.current)).then(()=>{h.current=i,_&&i.open()}),()=>{i.unmount(),h.current=null}},[a,s,r]),g.useEffect(()=>{var w;const i=h.current;i&&(i._cfg.theme=n,i._cfg.primaryColor=d,(w=i._applyTheme)==null||w.call(i))},[n,d]),f.jsx("div",{ref:L,"data-cognitiondesk-root":""})});l.CognitionDeskWidget=N,l.CognitionDeskWidgetCore=k,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
|