@aikaara/chat-sdk 0.2.0 → 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/dist/AikaaraChatClient-Cqbcd1jb.mjs +11538 -0
- package/dist/AikaaraChatClient-kAu65hX-.cjs +8 -0
- package/dist/cdn/aikaara-chat.iife.js +117 -24
- package/dist/headless.cjs +1 -8
- package/dist/headless.d.ts +275 -5
- package/dist/headless.mjs +85 -10531
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +291 -5
- package/dist/index.mjs +29 -24
- package/dist/ui.cjs +111 -18
- package/dist/ui.d.ts +294 -5
- package/dist/ui.mjs +310 -88
- package/package.json +1 -1
- package/dist/AikaaraChatClient-C4lWcRsS.mjs +0 -611
- package/dist/AikaaraChatClient-ChZ2bL9f.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 y {
|
|
|
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 y {
|
|
|
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) {
|
|
@@ -70,7 +77,7 @@ class y {
|
|
|
70
77
|
}, 200));
|
|
71
78
|
}
|
|
72
79
|
}
|
|
73
|
-
class
|
|
80
|
+
class S extends HTMLElement {
|
|
74
81
|
shadow;
|
|
75
82
|
controller = null;
|
|
76
83
|
_config = {};
|
|
@@ -115,38 +122,45 @@ class w extends HTMLElement {
|
|
|
115
122
|
apiKey: this.getAttribute("api-key") || this._config.apiKey,
|
|
116
123
|
title: this.getAttribute("title") || this._config.title || "Chat",
|
|
117
124
|
subtitle: this.getAttribute("subtitle") || this._config.subtitle,
|
|
118
|
-
theme: this.getAttribute("theme") || this._config.theme ||
|
|
119
|
-
primaryColor: this.getAttribute("primary-color") || this._config.primaryColor ||
|
|
120
|
-
position: this.getAttribute("position") || this._config.position ||
|
|
121
|
-
width: Number(this.getAttribute("width")) || this._config.width ||
|
|
122
|
-
height: Number(this.getAttribute("height")) || this._config.height ||
|
|
123
|
-
fontFamily: this._config.fontFamily ||
|
|
124
|
-
borderRadius: this._config.borderRadius ??
|
|
125
|
-
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,
|
|
126
133
|
welcomeMessage: this.getAttribute("welcome-message") || this._config.welcomeMessage,
|
|
127
134
|
avatarUrl: this.getAttribute("avatar-url") || this._config.avatarUrl,
|
|
128
135
|
showTimestamps: this._config.showTimestamps ?? !0,
|
|
129
136
|
persistConversation: this._config.persistConversation ?? !0,
|
|
130
137
|
showBubble: this._config.showBubble ?? !0,
|
|
131
|
-
offset: this._config.offset ||
|
|
138
|
+
offset: this._config.offset || y,
|
|
132
139
|
conversationId: this._config.conversationId,
|
|
133
140
|
systemPromptId: this._config.systemPromptId,
|
|
134
141
|
channel: this._config.channel,
|
|
135
142
|
extUid: this._config.extUid,
|
|
143
|
+
transport: this._config.transport,
|
|
144
|
+
tiledesk: this._config.tiledesk,
|
|
145
|
+
tiledeskIdentity: this._config.tiledeskIdentity,
|
|
136
146
|
onMessage: this._config.onMessage,
|
|
137
147
|
onStatusChange: this._config.onStatusChange,
|
|
138
148
|
onError: this._config.onError,
|
|
139
149
|
onStreamUpdate: this._config.onStreamUpdate,
|
|
140
|
-
onConnectionStateChange: this._config.onConnectionStateChange
|
|
150
|
+
onConnectionStateChange: this._config.onConnectionStateChange,
|
|
151
|
+
onTemplateMessage: this._config.onTemplateMessage
|
|
141
152
|
};
|
|
142
153
|
}
|
|
154
|
+
setUploadAdapter(e) {
|
|
155
|
+
this._config.uploadAdapter = e, this.controller?.getClient().setUploadAdapter(e);
|
|
156
|
+
}
|
|
143
157
|
render() {
|
|
144
158
|
const e = this.getConfig();
|
|
145
159
|
this.shadow.innerHTML = `
|
|
146
160
|
<style>
|
|
147
161
|
:host {
|
|
148
162
|
--aikaara-primary: ${e.primaryColor};
|
|
149
|
-
--aikaara-primary-hover: ${this.darkenColor(e.primaryColor ||
|
|
163
|
+
--aikaara-primary-hover: ${this.darkenColor(e.primaryColor || b)};
|
|
150
164
|
--aikaara-bg: #ffffff;
|
|
151
165
|
--aikaara-bg-secondary: #f9fafb;
|
|
152
166
|
--aikaara-text: #1f2937;
|
|
@@ -228,14 +242,16 @@ class w extends HTMLElement {
|
|
|
228
242
|
${e.avatarUrl ? `avatar-url="${e.avatarUrl}"` : ""}
|
|
229
243
|
></aikaara-chat-header>
|
|
230
244
|
<aikaara-message-list></aikaara-message-list>
|
|
231
|
-
<aikaara-chat-input placeholder="${e.placeholder ||
|
|
245
|
+
<aikaara-chat-input placeholder="${e.placeholder || u}"></aikaara-chat-input>
|
|
232
246
|
<aikaara-error-banner></aikaara-error-banner>
|
|
233
247
|
</div>
|
|
234
248
|
`;
|
|
235
249
|
}
|
|
236
250
|
async initController() {
|
|
237
251
|
const e = this.getConfig();
|
|
238
|
-
!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());
|
|
239
255
|
}
|
|
240
256
|
sendUserEvent(e, t, a) {
|
|
241
257
|
this.controller?.sendUserEvent(e, t, a);
|
|
@@ -245,14 +261,14 @@ class w extends HTMLElement {
|
|
|
245
261
|
}
|
|
246
262
|
darkenColor(e) {
|
|
247
263
|
try {
|
|
248
|
-
const t = parseInt(e.replace("#", ""), 16), a = Math.max(0, (t >> 16) - 20),
|
|
249
|
-
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")}`;
|
|
250
266
|
} catch {
|
|
251
267
|
return e;
|
|
252
268
|
}
|
|
253
269
|
}
|
|
254
270
|
}
|
|
255
|
-
class
|
|
271
|
+
class M extends HTMLElement {
|
|
256
272
|
shadow;
|
|
257
273
|
constructor() {
|
|
258
274
|
super(), this.shadow = this.attachShadow({ mode: "open" });
|
|
@@ -305,7 +321,7 @@ class T extends HTMLElement {
|
|
|
305
321
|
t && (t.innerHTML = e);
|
|
306
322
|
}
|
|
307
323
|
}
|
|
308
|
-
class
|
|
324
|
+
class _ extends HTMLElement {
|
|
309
325
|
shadow;
|
|
310
326
|
static get observedAttributes() {
|
|
311
327
|
return ["title", "subtitle", "avatar-url", "status"];
|
|
@@ -325,7 +341,7 @@ class C extends HTMLElement {
|
|
|
325
341
|
});
|
|
326
342
|
}
|
|
327
343
|
render() {
|
|
328
|
-
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";
|
|
329
345
|
this.shadow.innerHTML = `
|
|
330
346
|
<style>
|
|
331
347
|
.header {
|
|
@@ -410,7 +426,7 @@ class C extends HTMLElement {
|
|
|
410
426
|
<div class="info">
|
|
411
427
|
<div class="title">
|
|
412
428
|
${e}
|
|
413
|
-
<span class="status-dot" style="background:${
|
|
429
|
+
<span class="status-dot" style="background:${r}"></span>
|
|
414
430
|
</div>
|
|
415
431
|
${t ? `<div class="subtitle">${t}</div>` : ""}
|
|
416
432
|
</div>
|
|
@@ -426,14 +442,14 @@ class C extends HTMLElement {
|
|
|
426
442
|
this.setAttribute("status", e);
|
|
427
443
|
}
|
|
428
444
|
}
|
|
429
|
-
function
|
|
430
|
-
let e =
|
|
431
|
-
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(
|
|
432
448
|
/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g,
|
|
433
449
|
'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
|
|
434
450
|
), e = e.replace(/\n/g, "<br>"), e;
|
|
435
451
|
}
|
|
436
|
-
function
|
|
452
|
+
function $(s) {
|
|
437
453
|
const e = {
|
|
438
454
|
"&": "&",
|
|
439
455
|
"<": "<",
|
|
@@ -441,9 +457,9 @@ function L(i) {
|
|
|
441
457
|
'"': """,
|
|
442
458
|
"'": "'"
|
|
443
459
|
};
|
|
444
|
-
return
|
|
460
|
+
return s.replace(/[&<>"']/g, (t) => e[t]);
|
|
445
461
|
}
|
|
446
|
-
const
|
|
462
|
+
const H = /* @__PURE__ */ new Set([
|
|
447
463
|
"p",
|
|
448
464
|
"br",
|
|
449
465
|
"strong",
|
|
@@ -463,38 +479,38 @@ const A = /* @__PURE__ */ new Set([
|
|
|
463
479
|
"h6",
|
|
464
480
|
"span",
|
|
465
481
|
"div"
|
|
466
|
-
]),
|
|
482
|
+
]), z = {
|
|
467
483
|
a: /* @__PURE__ */ new Set(["href", "target", "rel"]),
|
|
468
484
|
code: /* @__PURE__ */ new Set(["class"]),
|
|
469
485
|
pre: /* @__PURE__ */ new Set(["class"]),
|
|
470
486
|
span: /* @__PURE__ */ new Set(["class"]),
|
|
471
487
|
div: /* @__PURE__ */ new Set(["class"])
|
|
472
488
|
};
|
|
473
|
-
function
|
|
489
|
+
function d(s) {
|
|
474
490
|
const e = document.createElement("template");
|
|
475
|
-
return e.innerHTML =
|
|
491
|
+
return e.innerHTML = s, g(e.content), e.innerHTML;
|
|
476
492
|
}
|
|
477
|
-
function
|
|
478
|
-
const e = Array.from(
|
|
493
|
+
function g(s) {
|
|
494
|
+
const e = Array.from(s.childNodes);
|
|
479
495
|
for (const t of e)
|
|
480
496
|
if (t.nodeType === Node.ELEMENT_NODE) {
|
|
481
|
-
const a = t,
|
|
482
|
-
if (!
|
|
483
|
-
const
|
|
484
|
-
|
|
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);
|
|
485
501
|
continue;
|
|
486
502
|
}
|
|
487
|
-
const
|
|
488
|
-
for (const
|
|
489
|
-
|
|
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);
|
|
490
506
|
if (a.hasAttribute("href")) {
|
|
491
|
-
const
|
|
492
|
-
!
|
|
507
|
+
const n = a.getAttribute("href") || "";
|
|
508
|
+
!n.startsWith("http://") && !n.startsWith("https://") && !n.startsWith("/") && a.removeAttribute("href");
|
|
493
509
|
}
|
|
494
|
-
|
|
510
|
+
g(t);
|
|
495
511
|
}
|
|
496
512
|
}
|
|
497
|
-
class
|
|
513
|
+
class I extends HTMLElement {
|
|
498
514
|
shadow;
|
|
499
515
|
container;
|
|
500
516
|
welcomeMessage = "";
|
|
@@ -524,7 +540,41 @@ class S extends HTMLElement {
|
|
|
524
540
|
.message-list::-webkit-scrollbar-thumb { background: var(--aikaara-border, #e5e7eb); border-radius: 3px; }
|
|
525
541
|
.message-wrap { display: flex; flex-direction: column; }
|
|
526
542
|
.message-wrap.user { align-items: flex-end; }
|
|
527
|
-
.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; }
|
|
528
578
|
.bubble {
|
|
529
579
|
max-width: 85%;
|
|
530
580
|
padding: 10px 14px;
|
|
@@ -622,7 +672,7 @@ class S extends HTMLElement {
|
|
|
622
672
|
renderMessages(e) {
|
|
623
673
|
if (this.container) {
|
|
624
674
|
if (this.container.innerHTML = "", e.length === 0 && this.welcomeMessage) {
|
|
625
|
-
this.container.innerHTML = `<div class="welcome">${l(
|
|
675
|
+
this.container.innerHTML = `<div class="welcome">${d(l(this.welcomeMessage))}</div>`;
|
|
626
676
|
return;
|
|
627
677
|
}
|
|
628
678
|
for (const t of e)
|
|
@@ -636,7 +686,7 @@ class S extends HTMLElement {
|
|
|
636
686
|
}
|
|
637
687
|
updateStreamingContent(e) {
|
|
638
688
|
const t = this.container.querySelector('[data-streaming="true"] .bubble');
|
|
639
|
-
t && (t.innerHTML = l(
|
|
689
|
+
t && (t.innerHTML = d(l(e)), t.classList.add("streaming-cursor"), this.scrollToBottom());
|
|
640
690
|
}
|
|
641
691
|
finalizeStreaming() {
|
|
642
692
|
const e = this.container.querySelector('[data-streaming="true"]');
|
|
@@ -652,14 +702,52 @@ class S extends HTMLElement {
|
|
|
652
702
|
}
|
|
653
703
|
appendMessageElement(e) {
|
|
654
704
|
const t = document.createElement("div");
|
|
655
|
-
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;
|
|
656
706
|
const a = document.createElement("div");
|
|
657
|
-
if (a.classList.add("bubble", e.role), e.role === "user" ? a.textContent = e.content : (a.innerHTML = l(
|
|
658
|
-
const
|
|
659
|
-
|
|
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);
|
|
660
732
|
}
|
|
661
733
|
this.container.appendChild(t);
|
|
662
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
|
+
}
|
|
663
751
|
scrollToBottom() {
|
|
664
752
|
requestAnimationFrame(() => {
|
|
665
753
|
this.container.scrollTop = this.container.scrollHeight;
|
|
@@ -673,10 +761,12 @@ class S extends HTMLElement {
|
|
|
673
761
|
}
|
|
674
762
|
}
|
|
675
763
|
}
|
|
676
|
-
class
|
|
764
|
+
class U extends HTMLElement {
|
|
677
765
|
shadow;
|
|
766
|
+
templatePayload = null;
|
|
767
|
+
attachments = [];
|
|
678
768
|
static get observedAttributes() {
|
|
679
|
-
return ["role", "content", "timestamp"];
|
|
769
|
+
return ["role", "content", "timestamp", "content-type", "template-id", "inner-message", "message-id", "status"];
|
|
680
770
|
}
|
|
681
771
|
constructor() {
|
|
682
772
|
super(), this.shadow = this.attachShadow({ mode: "open" });
|
|
@@ -687,13 +777,21 @@ class M extends HTMLElement {
|
|
|
687
777
|
attributeChangedCallback() {
|
|
688
778
|
this.render();
|
|
689
779
|
}
|
|
780
|
+
setTemplatePayload(e) {
|
|
781
|
+
this.templatePayload = e, this.render();
|
|
782
|
+
}
|
|
783
|
+
setAttachments(e) {
|
|
784
|
+
this.attachments = e, this.render();
|
|
785
|
+
}
|
|
690
786
|
render() {
|
|
691
|
-
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" ? "✓✓" : "";
|
|
692
788
|
this.shadow.innerHTML = `
|
|
693
789
|
<style>
|
|
694
790
|
:host { display: flex; flex-direction: column; }
|
|
695
791
|
:host([role="user"]) { align-items: flex-end; }
|
|
696
|
-
:host([role="assistant"])
|
|
792
|
+
:host([role="assistant"]),
|
|
793
|
+
:host([role="agent"]),
|
|
794
|
+
:host([role="system"]) { align-items: flex-start; }
|
|
697
795
|
.bubble {
|
|
698
796
|
max-width: 85%;
|
|
699
797
|
padding: 10px 14px;
|
|
@@ -707,24 +805,90 @@ class M extends HTMLElement {
|
|
|
707
805
|
color: #fff;
|
|
708
806
|
border-bottom-right-radius: 4px;
|
|
709
807
|
}
|
|
710
|
-
.bubble.assistant {
|
|
808
|
+
.bubble.assistant, .bubble.agent {
|
|
711
809
|
background: var(--aikaara-bg-secondary, #f9fafb);
|
|
712
810
|
color: var(--aikaara-text, #1f2937);
|
|
713
811
|
border-bottom-left-radius: 4px;
|
|
714
812
|
}
|
|
813
|
+
.bubble.system {
|
|
814
|
+
background: transparent;
|
|
815
|
+
color: var(--aikaara-text-secondary, #6b7280);
|
|
816
|
+
font-size: 12px;
|
|
817
|
+
font-style: italic;
|
|
818
|
+
}
|
|
715
819
|
.timestamp {
|
|
716
820
|
font-size: 11px;
|
|
717
821
|
color: var(--aikaara-text-secondary, #6b7280);
|
|
718
822
|
margin-top: 2px;
|
|
719
823
|
padding: 0 4px;
|
|
720
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; }
|
|
721
850
|
</style>
|
|
722
|
-
<div class="bubble ${e}"
|
|
723
|
-
|
|
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
|
+
` : ""}
|
|
724
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>` : "";
|
|
725
883
|
}
|
|
726
884
|
}
|
|
727
|
-
|
|
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 {
|
|
728
892
|
shadow;
|
|
729
893
|
textarea;
|
|
730
894
|
sendBtn;
|
|
@@ -822,7 +986,7 @@ class _ extends HTMLElement {
|
|
|
822
986
|
this.textarea.style.height = "auto", this.textarea.style.height = Math.min(this.textarea.scrollHeight, 120) + "px";
|
|
823
987
|
}
|
|
824
988
|
}
|
|
825
|
-
class
|
|
989
|
+
class D extends HTMLElement {
|
|
826
990
|
shadow;
|
|
827
991
|
constructor() {
|
|
828
992
|
super(), this.shadow = this.attachShadow({ mode: "open" });
|
|
@@ -871,7 +1035,7 @@ class H extends HTMLElement {
|
|
|
871
1035
|
this.removeAttribute("visible");
|
|
872
1036
|
}
|
|
873
1037
|
}
|
|
874
|
-
class
|
|
1038
|
+
class F extends HTMLElement {
|
|
875
1039
|
shadow;
|
|
876
1040
|
bubble;
|
|
877
1041
|
constructor() {
|
|
@@ -930,13 +1094,13 @@ class $ extends HTMLElement {
|
|
|
930
1094
|
`, this.bubble = this.shadow.querySelector(".bubble");
|
|
931
1095
|
}
|
|
932
1096
|
updateContent(e) {
|
|
933
|
-
this.bubble && (this.bubble.innerHTML = l(
|
|
1097
|
+
this.bubble && (this.bubble.innerHTML = d(l(e)), this.bubble.classList.add("cursor"));
|
|
934
1098
|
}
|
|
935
1099
|
finalize() {
|
|
936
1100
|
this.bubble?.classList.remove("cursor");
|
|
937
1101
|
}
|
|
938
1102
|
}
|
|
939
|
-
class
|
|
1103
|
+
class P extends HTMLElement {
|
|
940
1104
|
shadow;
|
|
941
1105
|
container;
|
|
942
1106
|
dismissTimer = null;
|
|
@@ -982,31 +1146,89 @@ class z extends HTMLElement {
|
|
|
982
1146
|
this.container.classList.remove("visible"), this.dismissTimer && (clearTimeout(this.dismissTimer), this.dismissTimer = null);
|
|
983
1147
|
}
|
|
984
1148
|
}
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
["
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
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]
|
|
996
1217
|
];
|
|
997
|
-
for (const [e, t] of
|
|
1218
|
+
for (const [e, t] of s)
|
|
998
1219
|
customElements.get(e) || customElements.define(e, t);
|
|
999
1220
|
}
|
|
1000
|
-
|
|
1221
|
+
N();
|
|
1001
1222
|
export {
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
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
|
|
1012
1234
|
};
|