@aikaara/chat-sdk 0.1.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +435 -0
- package/dist/AikaaraChatClient-Cqbcd1jb.mjs +11538 -0
- package/dist/AikaaraChatClient-kAu65hX-.cjs +8 -0
- package/dist/cdn/aikaara-chat.iife.js +118 -18
- package/dist/headless.cjs +1 -1
- package/dist/headless.d.ts +523 -5
- package/dist/headless.mjs +142 -9
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +541 -5
- package/dist/index.mjs +36 -28
- package/dist/ui.cjs +111 -18
- package/dist/ui.d.ts +498 -3
- package/dist/ui.mjs +322 -88
- package/package.json +4 -1
- package/dist/headless-BhsiNVQj.mjs +0 -551
- package/dist/headless-CrgIWcf7.cjs +0 -1
package/dist/ui.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
class
|
|
1
|
+
import { a as k, D as y, g as u, h as v, j as w, k as T, l as C, m as L, n as b, o as A } from "./AikaaraChatClient-Cqbcd1jb.mjs";
|
|
2
|
+
class E {
|
|
3
3
|
client;
|
|
4
4
|
panel;
|
|
5
5
|
bubble;
|
|
@@ -8,8 +8,8 @@ class v {
|
|
|
8
8
|
input;
|
|
9
9
|
errorBanner;
|
|
10
10
|
isOpen = !1;
|
|
11
|
-
constructor(e, t) {
|
|
12
|
-
this.client = new
|
|
11
|
+
constructor(e, t, a) {
|
|
12
|
+
this.client = new k(e, { uploadAdapter: a?.uploadAdapter }), this.bubble = t.querySelector("aikaara-chat-bubble"), this.panel = t.querySelector(".aikaara-panel"), this.header = t.querySelector("aikaara-chat-header"), this.messageList = t.querySelector("aikaara-message-list"), this.input = t.querySelector("aikaara-chat-input"), this.errorBanner = t.querySelector("aikaara-error-banner"), e.welcomeMessage && this.messageList.setWelcomeMessage(e.welcomeMessage), e.showTimestamps !== void 0 && this.messageList.setShowTimestamps(e.showTimestamps), this.wireEvents();
|
|
13
13
|
}
|
|
14
14
|
async connect() {
|
|
15
15
|
try {
|
|
@@ -47,6 +47,13 @@ class v {
|
|
|
47
47
|
this.header.setStatus(e), e === "connected" ? (this.errorBanner.hide(), this.input.disabled = !1) : e === "reconnecting" ? (this.errorBanner.show("Connection lost. Reconnecting..."), this.input.disabled = !0) : e === "disconnected" && (this.input.disabled = !0);
|
|
48
48
|
}), this.client.on("error", (e) => {
|
|
49
49
|
this.errorBanner.show(e.message, 5e3);
|
|
50
|
+
}), this.client.on("message:received", (e) => {
|
|
51
|
+
this.messageList.upsertMessage(e);
|
|
52
|
+
}), this.client.on("message:updated", (e) => {
|
|
53
|
+
this.messageList.upsertMessage(e);
|
|
54
|
+
}), this.messageList.addEventListener("message-action", (e) => {
|
|
55
|
+
const t = e.detail;
|
|
56
|
+
t?.text && this.handleSend(t.text);
|
|
50
57
|
});
|
|
51
58
|
}
|
|
52
59
|
async handleSend(e) {
|
|
@@ -56,6 +63,12 @@ class v {
|
|
|
56
63
|
this.errorBanner.show("Failed to send message", 3e3);
|
|
57
64
|
}
|
|
58
65
|
}
|
|
66
|
+
sendUserEvent(e, t, a) {
|
|
67
|
+
this.client.sendUserEvent(e, t, a);
|
|
68
|
+
}
|
|
69
|
+
getClient() {
|
|
70
|
+
return this.client;
|
|
71
|
+
}
|
|
59
72
|
togglePanel(e) {
|
|
60
73
|
this.isOpen = e !== void 0 ? e : !this.isOpen, this.isOpen ? (this.panel.removeAttribute("hidden"), requestAnimationFrame(() => {
|
|
61
74
|
this.panel.classList.remove("entering"), this.panel.classList.add("visible"), this.input.focus();
|
|
@@ -64,7 +77,7 @@ class v {
|
|
|
64
77
|
}, 200));
|
|
65
78
|
}
|
|
66
79
|
}
|
|
67
|
-
class
|
|
80
|
+
class S extends HTMLElement {
|
|
68
81
|
shadow;
|
|
69
82
|
controller = null;
|
|
70
83
|
_config = {};
|
|
@@ -109,38 +122,45 @@ class w extends HTMLElement {
|
|
|
109
122
|
apiKey: this.getAttribute("api-key") || this._config.apiKey,
|
|
110
123
|
title: this.getAttribute("title") || this._config.title || "Chat",
|
|
111
124
|
subtitle: this.getAttribute("subtitle") || this._config.subtitle,
|
|
112
|
-
theme: this.getAttribute("theme") || this._config.theme ||
|
|
113
|
-
primaryColor: this.getAttribute("primary-color") || this._config.primaryColor ||
|
|
114
|
-
position: this.getAttribute("position") || this._config.position ||
|
|
115
|
-
width: Number(this.getAttribute("width")) || this._config.width ||
|
|
116
|
-
height: Number(this.getAttribute("height")) || this._config.height ||
|
|
117
|
-
fontFamily: this._config.fontFamily ||
|
|
118
|
-
borderRadius: this._config.borderRadius ??
|
|
119
|
-
placeholder: this.getAttribute("placeholder") || this._config.placeholder ||
|
|
125
|
+
theme: this.getAttribute("theme") || this._config.theme || A,
|
|
126
|
+
primaryColor: this.getAttribute("primary-color") || this._config.primaryColor || b,
|
|
127
|
+
position: this.getAttribute("position") || this._config.position || L,
|
|
128
|
+
width: Number(this.getAttribute("width")) || this._config.width || C,
|
|
129
|
+
height: Number(this.getAttribute("height")) || this._config.height || T,
|
|
130
|
+
fontFamily: this._config.fontFamily || w,
|
|
131
|
+
borderRadius: this._config.borderRadius ?? v,
|
|
132
|
+
placeholder: this.getAttribute("placeholder") || this._config.placeholder || u,
|
|
120
133
|
welcomeMessage: this.getAttribute("welcome-message") || this._config.welcomeMessage,
|
|
121
134
|
avatarUrl: this.getAttribute("avatar-url") || this._config.avatarUrl,
|
|
122
135
|
showTimestamps: this._config.showTimestamps ?? !0,
|
|
123
136
|
persistConversation: this._config.persistConversation ?? !0,
|
|
124
137
|
showBubble: this._config.showBubble ?? !0,
|
|
125
|
-
offset: this._config.offset ||
|
|
138
|
+
offset: this._config.offset || y,
|
|
126
139
|
conversationId: this._config.conversationId,
|
|
127
140
|
systemPromptId: this._config.systemPromptId,
|
|
128
141
|
channel: this._config.channel,
|
|
129
142
|
extUid: this._config.extUid,
|
|
143
|
+
transport: this._config.transport,
|
|
144
|
+
tiledesk: this._config.tiledesk,
|
|
145
|
+
tiledeskIdentity: this._config.tiledeskIdentity,
|
|
130
146
|
onMessage: this._config.onMessage,
|
|
131
147
|
onStatusChange: this._config.onStatusChange,
|
|
132
148
|
onError: this._config.onError,
|
|
133
149
|
onStreamUpdate: this._config.onStreamUpdate,
|
|
134
|
-
onConnectionStateChange: this._config.onConnectionStateChange
|
|
150
|
+
onConnectionStateChange: this._config.onConnectionStateChange,
|
|
151
|
+
onTemplateMessage: this._config.onTemplateMessage
|
|
135
152
|
};
|
|
136
153
|
}
|
|
154
|
+
setUploadAdapter(e) {
|
|
155
|
+
this._config.uploadAdapter = e, this.controller?.getClient().setUploadAdapter(e);
|
|
156
|
+
}
|
|
137
157
|
render() {
|
|
138
158
|
const e = this.getConfig();
|
|
139
159
|
this.shadow.innerHTML = `
|
|
140
160
|
<style>
|
|
141
161
|
:host {
|
|
142
162
|
--aikaara-primary: ${e.primaryColor};
|
|
143
|
-
--aikaara-primary-hover: ${this.darkenColor(e.primaryColor ||
|
|
163
|
+
--aikaara-primary-hover: ${this.darkenColor(e.primaryColor || b)};
|
|
144
164
|
--aikaara-bg: #ffffff;
|
|
145
165
|
--aikaara-bg-secondary: #f9fafb;
|
|
146
166
|
--aikaara-text: #1f2937;
|
|
@@ -222,25 +242,33 @@ class w extends HTMLElement {
|
|
|
222
242
|
${e.avatarUrl ? `avatar-url="${e.avatarUrl}"` : ""}
|
|
223
243
|
></aikaara-chat-header>
|
|
224
244
|
<aikaara-message-list></aikaara-message-list>
|
|
225
|
-
<aikaara-chat-input placeholder="${e.placeholder ||
|
|
245
|
+
<aikaara-chat-input placeholder="${e.placeholder || u}"></aikaara-chat-input>
|
|
226
246
|
<aikaara-error-banner></aikaara-error-banner>
|
|
227
247
|
</div>
|
|
228
248
|
`;
|
|
229
249
|
}
|
|
230
250
|
async initController() {
|
|
231
251
|
const e = this.getConfig();
|
|
232
|
-
!e.baseUrl || !e.userToken || (this.controller?.disconnect(), this.controller = new
|
|
252
|
+
!e.baseUrl || !e.userToken || (this.controller?.disconnect(), this.controller = new E(e, this.shadow, {
|
|
253
|
+
uploadAdapter: this._config.uploadAdapter
|
|
254
|
+
}), await this.controller.connect());
|
|
255
|
+
}
|
|
256
|
+
sendUserEvent(e, t, a) {
|
|
257
|
+
this.controller?.sendUserEvent(e, t, a);
|
|
258
|
+
}
|
|
259
|
+
getClient() {
|
|
260
|
+
return this.controller?.getClient() ?? null;
|
|
233
261
|
}
|
|
234
262
|
darkenColor(e) {
|
|
235
263
|
try {
|
|
236
|
-
const t = parseInt(e.replace("#", ""), 16), a = Math.max(0, (t >> 16) - 20),
|
|
237
|
-
return `#${(a << 16 |
|
|
264
|
+
const t = parseInt(e.replace("#", ""), 16), a = Math.max(0, (t >> 16) - 20), i = Math.max(0, (t >> 8 & 255) - 20), r = Math.max(0, (t & 255) - 20);
|
|
265
|
+
return `#${(a << 16 | i << 8 | r).toString(16).padStart(6, "0")}`;
|
|
238
266
|
} catch {
|
|
239
267
|
return e;
|
|
240
268
|
}
|
|
241
269
|
}
|
|
242
270
|
}
|
|
243
|
-
class
|
|
271
|
+
class M extends HTMLElement {
|
|
244
272
|
shadow;
|
|
245
273
|
constructor() {
|
|
246
274
|
super(), this.shadow = this.attachShadow({ mode: "open" });
|
|
@@ -293,7 +321,7 @@ class T extends HTMLElement {
|
|
|
293
321
|
t && (t.innerHTML = e);
|
|
294
322
|
}
|
|
295
323
|
}
|
|
296
|
-
class
|
|
324
|
+
class _ extends HTMLElement {
|
|
297
325
|
shadow;
|
|
298
326
|
static get observedAttributes() {
|
|
299
327
|
return ["title", "subtitle", "avatar-url", "status"];
|
|
@@ -313,7 +341,7 @@ class L extends HTMLElement {
|
|
|
313
341
|
});
|
|
314
342
|
}
|
|
315
343
|
render() {
|
|
316
|
-
const e = this.getAttribute("title") || "Chat", t = this.getAttribute("subtitle") || "", a = this.getAttribute("avatar-url"),
|
|
344
|
+
const e = this.getAttribute("title") || "Chat", t = this.getAttribute("subtitle") || "", a = this.getAttribute("avatar-url"), i = this.getAttribute("status") || "connected", r = i === "connected" ? "#10b981" : i === "connecting" || i === "reconnecting" ? "#f59e0b" : "#ef4444";
|
|
317
345
|
this.shadow.innerHTML = `
|
|
318
346
|
<style>
|
|
319
347
|
.header {
|
|
@@ -398,7 +426,7 @@ class L extends HTMLElement {
|
|
|
398
426
|
<div class="info">
|
|
399
427
|
<div class="title">
|
|
400
428
|
${e}
|
|
401
|
-
<span class="status-dot" style="background:${
|
|
429
|
+
<span class="status-dot" style="background:${r}"></span>
|
|
402
430
|
</div>
|
|
403
431
|
${t ? `<div class="subtitle">${t}</div>` : ""}
|
|
404
432
|
</div>
|
|
@@ -414,14 +442,14 @@ class L extends HTMLElement {
|
|
|
414
442
|
this.setAttribute("status", e);
|
|
415
443
|
}
|
|
416
444
|
}
|
|
417
|
-
function
|
|
418
|
-
let e =
|
|
419
|
-
return e = e.replace(/```(\w*)\n([\s\S]*?)```/g, (t, a,
|
|
445
|
+
function l(s) {
|
|
446
|
+
let e = $(s);
|
|
447
|
+
return e = e.replace(/```(\w*)\n([\s\S]*?)```/g, (t, a, i) => `<pre><code>${i.trim()}</code></pre>`), e = e.replace(/`([^`]+)`/g, "<code>$1</code>"), e = e.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>"), e = e.replace(/\*(.+?)\*/g, "<em>$1</em>"), e = e.replace(
|
|
420
448
|
/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g,
|
|
421
449
|
'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
|
|
422
450
|
), e = e.replace(/\n/g, "<br>"), e;
|
|
423
451
|
}
|
|
424
|
-
function
|
|
452
|
+
function $(s) {
|
|
425
453
|
const e = {
|
|
426
454
|
"&": "&",
|
|
427
455
|
"<": "<",
|
|
@@ -429,9 +457,9 @@ function C(i) {
|
|
|
429
457
|
'"': """,
|
|
430
458
|
"'": "'"
|
|
431
459
|
};
|
|
432
|
-
return
|
|
460
|
+
return s.replace(/[&<>"']/g, (t) => e[t]);
|
|
433
461
|
}
|
|
434
|
-
const
|
|
462
|
+
const H = /* @__PURE__ */ new Set([
|
|
435
463
|
"p",
|
|
436
464
|
"br",
|
|
437
465
|
"strong",
|
|
@@ -451,38 +479,38 @@ const A = /* @__PURE__ */ new Set([
|
|
|
451
479
|
"h6",
|
|
452
480
|
"span",
|
|
453
481
|
"div"
|
|
454
|
-
]),
|
|
482
|
+
]), z = {
|
|
455
483
|
a: /* @__PURE__ */ new Set(["href", "target", "rel"]),
|
|
456
484
|
code: /* @__PURE__ */ new Set(["class"]),
|
|
457
485
|
pre: /* @__PURE__ */ new Set(["class"]),
|
|
458
486
|
span: /* @__PURE__ */ new Set(["class"]),
|
|
459
487
|
div: /* @__PURE__ */ new Set(["class"])
|
|
460
488
|
};
|
|
461
|
-
function
|
|
489
|
+
function d(s) {
|
|
462
490
|
const e = document.createElement("template");
|
|
463
|
-
return e.innerHTML =
|
|
491
|
+
return e.innerHTML = s, g(e.content), e.innerHTML;
|
|
464
492
|
}
|
|
465
|
-
function
|
|
466
|
-
const e = Array.from(
|
|
493
|
+
function g(s) {
|
|
494
|
+
const e = Array.from(s.childNodes);
|
|
467
495
|
for (const t of e)
|
|
468
496
|
if (t.nodeType === Node.ELEMENT_NODE) {
|
|
469
|
-
const a = t,
|
|
470
|
-
if (!
|
|
471
|
-
const
|
|
472
|
-
|
|
497
|
+
const a = t, i = a.tagName.toLowerCase();
|
|
498
|
+
if (!H.has(i)) {
|
|
499
|
+
const n = document.createTextNode(a.textContent || "");
|
|
500
|
+
s.replaceChild(n, t);
|
|
473
501
|
continue;
|
|
474
502
|
}
|
|
475
|
-
const
|
|
476
|
-
for (const
|
|
477
|
-
|
|
503
|
+
const r = z[i] || /* @__PURE__ */ new Set(), o = Array.from(a.attributes);
|
|
504
|
+
for (const n of o)
|
|
505
|
+
r.has(n.name) || a.removeAttribute(n.name);
|
|
478
506
|
if (a.hasAttribute("href")) {
|
|
479
|
-
const
|
|
480
|
-
!
|
|
507
|
+
const n = a.getAttribute("href") || "";
|
|
508
|
+
!n.startsWith("http://") && !n.startsWith("https://") && !n.startsWith("/") && a.removeAttribute("href");
|
|
481
509
|
}
|
|
482
|
-
|
|
510
|
+
g(t);
|
|
483
511
|
}
|
|
484
512
|
}
|
|
485
|
-
class
|
|
513
|
+
class I extends HTMLElement {
|
|
486
514
|
shadow;
|
|
487
515
|
container;
|
|
488
516
|
welcomeMessage = "";
|
|
@@ -512,7 +540,41 @@ class E extends HTMLElement {
|
|
|
512
540
|
.message-list::-webkit-scrollbar-thumb { background: var(--aikaara-border, #e5e7eb); border-radius: 3px; }
|
|
513
541
|
.message-wrap { display: flex; flex-direction: column; }
|
|
514
542
|
.message-wrap.user { align-items: flex-end; }
|
|
515
|
-
.message-wrap.assistant
|
|
543
|
+
.message-wrap.assistant,
|
|
544
|
+
.message-wrap.agent,
|
|
545
|
+
.message-wrap.system { align-items: flex-start; }
|
|
546
|
+
.message-wrap.system .bubble {
|
|
547
|
+
background: transparent;
|
|
548
|
+
color: var(--aikaara-text-secondary, #6b7280);
|
|
549
|
+
font-size: 12px;
|
|
550
|
+
font-style: italic;
|
|
551
|
+
padding: 4px 0;
|
|
552
|
+
}
|
|
553
|
+
.attachments {
|
|
554
|
+
display: flex;
|
|
555
|
+
flex-direction: column;
|
|
556
|
+
gap: 4px;
|
|
557
|
+
margin-top: 6px;
|
|
558
|
+
}
|
|
559
|
+
.attachment {
|
|
560
|
+
display: inline-flex;
|
|
561
|
+
align-items: center;
|
|
562
|
+
gap: 6px;
|
|
563
|
+
padding: 6px 10px;
|
|
564
|
+
background: rgba(0,0,0,0.05);
|
|
565
|
+
border-radius: 8px;
|
|
566
|
+
font-size: 12px;
|
|
567
|
+
color: inherit;
|
|
568
|
+
text-decoration: none;
|
|
569
|
+
}
|
|
570
|
+
.attachment:hover { background: rgba(0,0,0,0.08); }
|
|
571
|
+
.status-tick {
|
|
572
|
+
font-size: 10px;
|
|
573
|
+
margin-left: 4px;
|
|
574
|
+
color: var(--aikaara-text-secondary, #6b7280);
|
|
575
|
+
}
|
|
576
|
+
.status-tick.read { color: var(--aikaara-primary, #6366f1); }
|
|
577
|
+
aikaara-template-renderer { display: block; margin-top: 6px; }
|
|
516
578
|
.bubble {
|
|
517
579
|
max-width: 85%;
|
|
518
580
|
padding: 10px 14px;
|
|
@@ -610,7 +672,7 @@ class E extends HTMLElement {
|
|
|
610
672
|
renderMessages(e) {
|
|
611
673
|
if (this.container) {
|
|
612
674
|
if (this.container.innerHTML = "", e.length === 0 && this.welcomeMessage) {
|
|
613
|
-
this.container.innerHTML = `<div class="welcome">${l(
|
|
675
|
+
this.container.innerHTML = `<div class="welcome">${d(l(this.welcomeMessage))}</div>`;
|
|
614
676
|
return;
|
|
615
677
|
}
|
|
616
678
|
for (const t of e)
|
|
@@ -624,7 +686,7 @@ class E extends HTMLElement {
|
|
|
624
686
|
}
|
|
625
687
|
updateStreamingContent(e) {
|
|
626
688
|
const t = this.container.querySelector('[data-streaming="true"] .bubble');
|
|
627
|
-
t && (t.innerHTML = l(
|
|
689
|
+
t && (t.innerHTML = d(l(e)), t.classList.add("streaming-cursor"), this.scrollToBottom());
|
|
628
690
|
}
|
|
629
691
|
finalizeStreaming() {
|
|
630
692
|
const e = this.container.querySelector('[data-streaming="true"]');
|
|
@@ -640,14 +702,52 @@ class E extends HTMLElement {
|
|
|
640
702
|
}
|
|
641
703
|
appendMessageElement(e) {
|
|
642
704
|
const t = document.createElement("div");
|
|
643
|
-
t.classList.add("message-wrap", e.role), e.status === "streaming" && t.setAttribute("data-streaming", "true");
|
|
705
|
+
t.classList.add("message-wrap", e.role), e.status === "streaming" && t.setAttribute("data-streaming", "true"), e.externalId && (t.dataset.externalId = e.externalId), t.dataset.messageId = e.id;
|
|
644
706
|
const a = document.createElement("div");
|
|
645
|
-
if (a.classList.add("bubble", e.role), e.role === "user" ? a.textContent = e.content : (a.innerHTML = l(
|
|
646
|
-
const
|
|
647
|
-
|
|
707
|
+
if (a.classList.add("bubble", e.role), e.role === "user" ? a.textContent = e.content : (a.innerHTML = d(l(e.content || "")), e.status === "streaming" && a.classList.add("streaming-cursor")), e.template?.contentType) {
|
|
708
|
+
const i = document.createElement("aikaara-template-renderer");
|
|
709
|
+
i.setAttribute("content-type", e.template.contentType), e.template.templateId && i.setAttribute("template-id", e.template.templateId), i.setPayload(e.template.payload, e.role !== "user" ? e.content : void 0), a.appendChild(i);
|
|
710
|
+
}
|
|
711
|
+
if (e.attachments?.length) {
|
|
712
|
+
const i = document.createElement("div");
|
|
713
|
+
i.classList.add("attachments");
|
|
714
|
+
for (const r of e.attachments) {
|
|
715
|
+
const o = document.createElement("a");
|
|
716
|
+
o.classList.add("attachment"), o.href = r.fileUrl, o.target = "_blank", o.rel = "noopener noreferrer", o.textContent = `📎 ${r.fileName}`, i.appendChild(o);
|
|
717
|
+
}
|
|
718
|
+
a.appendChild(i);
|
|
719
|
+
}
|
|
720
|
+
if (t.appendChild(a), this.showTimestamps && e.createdAt || e.role === "user" && e.status) {
|
|
721
|
+
const i = document.createElement("div");
|
|
722
|
+
if (i.classList.add("timestamp"), this.showTimestamps && e.createdAt && (i.textContent = this.formatTime(e.createdAt)), e.role === "user" && e.status) {
|
|
723
|
+
const r = document.createElement("span");
|
|
724
|
+
r.classList.add("status-tick"), e.status === "read" && r.classList.add("read"), r.textContent = {
|
|
725
|
+
sending: " ○",
|
|
726
|
+
sent: " ✓",
|
|
727
|
+
delivered: " ✓✓",
|
|
728
|
+
read: " ✓✓"
|
|
729
|
+
}[e.status] ?? "", i.appendChild(r);
|
|
730
|
+
}
|
|
731
|
+
t.appendChild(i);
|
|
648
732
|
}
|
|
649
733
|
this.container.appendChild(t);
|
|
650
734
|
}
|
|
735
|
+
/**
|
|
736
|
+
* Replace an existing rendered message (matched by id or externalId) in place.
|
|
737
|
+
* Used when a Tiledesk self-echo reconciles with an optimistic bubble or when
|
|
738
|
+
* a status update flips delivered → read.
|
|
739
|
+
*/
|
|
740
|
+
upsertMessage(e) {
|
|
741
|
+
const t = this.findRenderedMessage(e);
|
|
742
|
+
t && t.remove(), this.appendMessageElement(e), this.scrollToBottom();
|
|
743
|
+
}
|
|
744
|
+
findRenderedMessage(e) {
|
|
745
|
+
if (e.externalId) {
|
|
746
|
+
const t = this.container.querySelector(`[data-external-id="${CSS.escape(e.externalId)}"]`);
|
|
747
|
+
if (t) return t;
|
|
748
|
+
}
|
|
749
|
+
return this.container.querySelector(`[data-message-id="${CSS.escape(e.id)}"]`);
|
|
750
|
+
}
|
|
651
751
|
scrollToBottom() {
|
|
652
752
|
requestAnimationFrame(() => {
|
|
653
753
|
this.container.scrollTop = this.container.scrollHeight;
|
|
@@ -661,10 +761,12 @@ class E extends HTMLElement {
|
|
|
661
761
|
}
|
|
662
762
|
}
|
|
663
763
|
}
|
|
664
|
-
class
|
|
764
|
+
class U extends HTMLElement {
|
|
665
765
|
shadow;
|
|
766
|
+
templatePayload = null;
|
|
767
|
+
attachments = [];
|
|
666
768
|
static get observedAttributes() {
|
|
667
|
-
return ["role", "content", "timestamp"];
|
|
769
|
+
return ["role", "content", "timestamp", "content-type", "template-id", "inner-message", "message-id", "status"];
|
|
668
770
|
}
|
|
669
771
|
constructor() {
|
|
670
772
|
super(), this.shadow = this.attachShadow({ mode: "open" });
|
|
@@ -675,13 +777,21 @@ class M extends HTMLElement {
|
|
|
675
777
|
attributeChangedCallback() {
|
|
676
778
|
this.render();
|
|
677
779
|
}
|
|
780
|
+
setTemplatePayload(e) {
|
|
781
|
+
this.templatePayload = e, this.render();
|
|
782
|
+
}
|
|
783
|
+
setAttachments(e) {
|
|
784
|
+
this.attachments = e, this.render();
|
|
785
|
+
}
|
|
678
786
|
render() {
|
|
679
|
-
const e = this.getAttribute("role") || "user", t = this.getAttribute("content") || "", a = this.getAttribute("timestamp") || "",
|
|
787
|
+
const e = this.getAttribute("role") || "user", t = this.getAttribute("content") || "", a = this.getAttribute("timestamp") || "", i = this.getAttribute("status") || "", r = this.getAttribute("content-type") || "", o = this.getAttribute("template-id") || "", n = this.getAttribute("inner-message") || "", h = e === "user" ? document.createTextNode(t).textContent || "" : d(l(t)), p = e === "user" && i, f = i === "sending" ? "○" : i === "sent" ? "✓" : i === "delivered" || i === "read" ? "✓✓" : "";
|
|
680
788
|
this.shadow.innerHTML = `
|
|
681
789
|
<style>
|
|
682
790
|
:host { display: flex; flex-direction: column; }
|
|
683
791
|
:host([role="user"]) { align-items: flex-end; }
|
|
684
|
-
:host([role="assistant"])
|
|
792
|
+
:host([role="assistant"]),
|
|
793
|
+
:host([role="agent"]),
|
|
794
|
+
:host([role="system"]) { align-items: flex-start; }
|
|
685
795
|
.bubble {
|
|
686
796
|
max-width: 85%;
|
|
687
797
|
padding: 10px 14px;
|
|
@@ -695,24 +805,90 @@ class M extends HTMLElement {
|
|
|
695
805
|
color: #fff;
|
|
696
806
|
border-bottom-right-radius: 4px;
|
|
697
807
|
}
|
|
698
|
-
.bubble.assistant {
|
|
808
|
+
.bubble.assistant, .bubble.agent {
|
|
699
809
|
background: var(--aikaara-bg-secondary, #f9fafb);
|
|
700
810
|
color: var(--aikaara-text, #1f2937);
|
|
701
811
|
border-bottom-left-radius: 4px;
|
|
702
812
|
}
|
|
813
|
+
.bubble.system {
|
|
814
|
+
background: transparent;
|
|
815
|
+
color: var(--aikaara-text-secondary, #6b7280);
|
|
816
|
+
font-size: 12px;
|
|
817
|
+
font-style: italic;
|
|
818
|
+
}
|
|
703
819
|
.timestamp {
|
|
704
820
|
font-size: 11px;
|
|
705
821
|
color: var(--aikaara-text-secondary, #6b7280);
|
|
706
822
|
margin-top: 2px;
|
|
707
823
|
padding: 0 4px;
|
|
708
824
|
}
|
|
825
|
+
.status {
|
|
826
|
+
font-size: 10px;
|
|
827
|
+
color: ${i === "read" ? "var(--aikaara-primary, #6366f1)" : "var(--aikaara-text-secondary, #6b7280)"};
|
|
828
|
+
margin-left: 4px;
|
|
829
|
+
}
|
|
830
|
+
.attachments {
|
|
831
|
+
display: flex;
|
|
832
|
+
flex-direction: column;
|
|
833
|
+
gap: 6px;
|
|
834
|
+
margin-top: 8px;
|
|
835
|
+
}
|
|
836
|
+
.attachment {
|
|
837
|
+
display: inline-flex;
|
|
838
|
+
align-items: center;
|
|
839
|
+
gap: 6px;
|
|
840
|
+
padding: 6px 10px;
|
|
841
|
+
background: rgba(0,0,0,0.05);
|
|
842
|
+
border-radius: 8px;
|
|
843
|
+
font-size: 12px;
|
|
844
|
+
color: inherit;
|
|
845
|
+
text-decoration: none;
|
|
846
|
+
max-width: 100%;
|
|
847
|
+
}
|
|
848
|
+
.attachment:hover { background: rgba(0,0,0,0.08); }
|
|
849
|
+
aikaara-template-renderer { display: block; margin-top: 6px; }
|
|
709
850
|
</style>
|
|
710
|
-
<div class="bubble ${e}"
|
|
711
|
-
|
|
851
|
+
<div class="bubble ${e}">
|
|
852
|
+
<div class="content">${h}</div>
|
|
853
|
+
${r ? `<aikaara-template-renderer
|
|
854
|
+
content-type="${r}"
|
|
855
|
+
template-id="${o}"
|
|
856
|
+
inner-message="${m(n)}"
|
|
857
|
+
></aikaara-template-renderer>` : ""}
|
|
858
|
+
${this.renderAttachments()}
|
|
859
|
+
</div>
|
|
860
|
+
${a || p ? `
|
|
861
|
+
<div class="timestamp">
|
|
862
|
+
${a}${p ? `<span class="status">${f}</span>` : ""}
|
|
863
|
+
</div>
|
|
864
|
+
` : ""}
|
|
712
865
|
`;
|
|
866
|
+
const c = this.shadow.querySelector("aikaara-template-renderer");
|
|
867
|
+
c && this.templatePayload !== null && c.setPayload(this.templatePayload, n), c && c.addEventListener("template-action", (x) => {
|
|
868
|
+
this.dispatchEvent(
|
|
869
|
+
new CustomEvent("message-action", {
|
|
870
|
+
detail: x.detail,
|
|
871
|
+
bubbles: !0,
|
|
872
|
+
composed: !0
|
|
873
|
+
})
|
|
874
|
+
);
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
renderAttachments() {
|
|
878
|
+
return this.attachments.length ? `<div class="attachments">${this.attachments.map(
|
|
879
|
+
(t) => `<a class="attachment" href="${m(t.fileUrl)}" target="_blank" rel="noopener noreferrer">
|
|
880
|
+
📎 ${q(t.fileName)}
|
|
881
|
+
</a>`
|
|
882
|
+
).join("")}</div>` : "";
|
|
713
883
|
}
|
|
714
884
|
}
|
|
715
|
-
|
|
885
|
+
function m(s) {
|
|
886
|
+
return String(s).replace(/[&<>"']/g, (e) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[e]);
|
|
887
|
+
}
|
|
888
|
+
function q(s) {
|
|
889
|
+
return String(s).replace(/[&<>]/g, (e) => ({ "&": "&", "<": "<", ">": ">" })[e]);
|
|
890
|
+
}
|
|
891
|
+
class B extends HTMLElement {
|
|
716
892
|
shadow;
|
|
717
893
|
textarea;
|
|
718
894
|
sendBtn;
|
|
@@ -810,7 +986,7 @@ class _ extends HTMLElement {
|
|
|
810
986
|
this.textarea.style.height = "auto", this.textarea.style.height = Math.min(this.textarea.scrollHeight, 120) + "px";
|
|
811
987
|
}
|
|
812
988
|
}
|
|
813
|
-
class
|
|
989
|
+
class D extends HTMLElement {
|
|
814
990
|
shadow;
|
|
815
991
|
constructor() {
|
|
816
992
|
super(), this.shadow = this.attachShadow({ mode: "open" });
|
|
@@ -859,7 +1035,7 @@ class H extends HTMLElement {
|
|
|
859
1035
|
this.removeAttribute("visible");
|
|
860
1036
|
}
|
|
861
1037
|
}
|
|
862
|
-
class
|
|
1038
|
+
class F extends HTMLElement {
|
|
863
1039
|
shadow;
|
|
864
1040
|
bubble;
|
|
865
1041
|
constructor() {
|
|
@@ -918,13 +1094,13 @@ class $ extends HTMLElement {
|
|
|
918
1094
|
`, this.bubble = this.shadow.querySelector(".bubble");
|
|
919
1095
|
}
|
|
920
1096
|
updateContent(e) {
|
|
921
|
-
this.bubble && (this.bubble.innerHTML = l(
|
|
1097
|
+
this.bubble && (this.bubble.innerHTML = d(l(e)), this.bubble.classList.add("cursor"));
|
|
922
1098
|
}
|
|
923
1099
|
finalize() {
|
|
924
1100
|
this.bubble?.classList.remove("cursor");
|
|
925
1101
|
}
|
|
926
1102
|
}
|
|
927
|
-
class
|
|
1103
|
+
class P extends HTMLElement {
|
|
928
1104
|
shadow;
|
|
929
1105
|
container;
|
|
930
1106
|
dismissTimer = null;
|
|
@@ -970,31 +1146,89 @@ class z extends HTMLElement {
|
|
|
970
1146
|
this.container.classList.remove("visible"), this.dismissTimer && (clearTimeout(this.dismissTimer), this.dismissTimer = null);
|
|
971
1147
|
}
|
|
972
1148
|
}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
["
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1149
|
+
class O extends HTMLElement {
|
|
1150
|
+
shadow;
|
|
1151
|
+
payloadData = null;
|
|
1152
|
+
innerMessage = "";
|
|
1153
|
+
static get observedAttributes() {
|
|
1154
|
+
return ["content-type", "template-id", "inner-message"];
|
|
1155
|
+
}
|
|
1156
|
+
constructor() {
|
|
1157
|
+
super(), this.shadow = this.attachShadow({ mode: "open" });
|
|
1158
|
+
}
|
|
1159
|
+
connectedCallback() {
|
|
1160
|
+
this.render();
|
|
1161
|
+
}
|
|
1162
|
+
attributeChangedCallback() {
|
|
1163
|
+
this.render();
|
|
1164
|
+
}
|
|
1165
|
+
setPayload(e, t) {
|
|
1166
|
+
this.payloadData = e, t !== void 0 && (this.innerMessage = t), this.render();
|
|
1167
|
+
}
|
|
1168
|
+
render() {
|
|
1169
|
+
const e = this.getAttribute("content-type") ?? "", t = this.getAttribute("template-id") ?? "", a = this.getAttribute("inner-message") ?? this.innerMessage;
|
|
1170
|
+
this.shadow.innerHTML = `
|
|
1171
|
+
<style>
|
|
1172
|
+
:host { display: block; }
|
|
1173
|
+
.inner { font-size: 14px; line-height: 1.5; color: var(--aikaara-text, #1f2937); }
|
|
1174
|
+
.placeholder {
|
|
1175
|
+
font-size: 12px;
|
|
1176
|
+
color: var(--aikaara-text-secondary, #6b7280);
|
|
1177
|
+
padding: 6px 0;
|
|
1178
|
+
}
|
|
1179
|
+
</style>
|
|
1180
|
+
${a ? '<div class="inner"></div>' : ""}
|
|
1181
|
+
<slot></slot>
|
|
1182
|
+
`;
|
|
1183
|
+
const i = this.shadow.querySelector(".inner");
|
|
1184
|
+
if (i && a && (i.textContent = a), !e) return;
|
|
1185
|
+
const r = t ? `aikaara-template-${t}` : `aikaara-template-${e}`;
|
|
1186
|
+
if (customElements.get(r)) {
|
|
1187
|
+
const o = this.querySelector(r);
|
|
1188
|
+
if (o) {
|
|
1189
|
+
o.setPayload?.(this.payloadData);
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
const n = document.createElement(r);
|
|
1193
|
+
n.setPayload?.(this.payloadData), n.addEventListener("template-action", (h) => {
|
|
1194
|
+
this.dispatchEvent(
|
|
1195
|
+
new CustomEvent("template-action", {
|
|
1196
|
+
detail: h.detail,
|
|
1197
|
+
bubbles: !0,
|
|
1198
|
+
composed: !0
|
|
1199
|
+
})
|
|
1200
|
+
);
|
|
1201
|
+
}), this.appendChild(n);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
function N() {
|
|
1206
|
+
const s = [
|
|
1207
|
+
["aikaara-chat-widget", S],
|
|
1208
|
+
["aikaara-chat-bubble", M],
|
|
1209
|
+
["aikaara-chat-header", _],
|
|
1210
|
+
["aikaara-message-list", I],
|
|
1211
|
+
["aikaara-message-bubble", U],
|
|
1212
|
+
["aikaara-chat-input", B],
|
|
1213
|
+
["aikaara-typing-indicator", D],
|
|
1214
|
+
["aikaara-streaming-message", F],
|
|
1215
|
+
["aikaara-error-banner", P],
|
|
1216
|
+
["aikaara-template-renderer", O]
|
|
984
1217
|
];
|
|
985
|
-
for (const [e, t] of
|
|
1218
|
+
for (const [e, t] of s)
|
|
986
1219
|
customElements.get(e) || customElements.define(e, t);
|
|
987
1220
|
}
|
|
988
|
-
|
|
1221
|
+
N();
|
|
989
1222
|
export {
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1223
|
+
M as AikaaraChatBubble,
|
|
1224
|
+
_ as AikaaraChatHeader,
|
|
1225
|
+
B as AikaaraChatInput,
|
|
1226
|
+
S as AikaaraChatWidget,
|
|
1227
|
+
P as AikaaraErrorBanner,
|
|
1228
|
+
U as AikaaraMessageBubble,
|
|
1229
|
+
I as AikaaraMessageList,
|
|
1230
|
+
F as AikaaraStreamingMessage,
|
|
1231
|
+
O as AikaaraTemplateRenderer,
|
|
1232
|
+
D as AikaaraTypingIndicator,
|
|
1233
|
+
N as registerComponents
|
|
1000
1234
|
};
|