@aikaara/chat-sdk 0.3.0 → 0.3.3

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/ui.cjs CHANGED
@@ -1,621 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("./AikaaraChatClient-kAu65hX-.cjs");class S{client;panel;bubble;header;messageList;input;errorBanner;isOpen=!1;constructor(e,t,a){this.client=new l.AikaaraChatClient(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()}async connect(){try{await this.client.connect(),this.messageList.renderMessages(this.client.messages)}catch{this.errorBanner.show("Failed to connect. Retrying...",5e3)}}async disconnect(){await this.client.disconnect()}wireEvents(){this.bubble.addEventListener("toggle",()=>{this.togglePanel()}),this.header.addEventListener("header-close",()=>{this.togglePanel(!1)}),this.input.addEventListener("send",(e=>{this.handleSend(e.detail.content)})),this.client.on("message:sent",e=>{this.messageList.addMessage(e)}),this.client.on("stream:start",()=>{this.messageList.removeTypingIndicator();const e=this.client.messages[this.client.messages.length-1];e&&this.messageList.addMessage(e)}),this.client.on("stream:update",({content:e})=>{this.messageList.updateStreamingContent(e)}),this.client.on("stream:end",()=>{this.messageList.finalizeStreaming()}),this.client.on("typing:start",()=>{const e=this.client.messages,t=e[e.length-1];(!t||t.status!=="streaming")&&this.messageList.showTypingIndicator()}),this.client.on("typing:stop",()=>{this.messageList.removeTypingIndicator()}),this.client.on("connection:state",e=>{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)}),this.client.on("error",e=>{this.errorBanner.show(e.message,5e3)}),this.client.on("message:received",e=>{this.messageList.upsertMessage(e)}),this.client.on("message:updated",e=>{this.messageList.upsertMessage(e)}),this.messageList.addEventListener("message-action",e=>{const t=e.detail;t?.text&&this.handleSend(t.text)})}async handleSend(e){try{await this.client.sendMessage(e)}catch{this.errorBanner.show("Failed to send message",3e3)}}sendUserEvent(e,t,a){this.client.sendUserEvent(e,t,a)}getClient(){return this.client}togglePanel(e){this.isOpen=e!==void 0?e:!this.isOpen,this.isOpen?(this.panel.removeAttribute("hidden"),requestAnimationFrame(()=>{this.panel.classList.remove("entering"),this.panel.classList.add("visible"),this.input.focus()})):(this.panel.classList.remove("visible"),this.panel.classList.add("entering"),setTimeout(()=>{this.panel.setAttribute("hidden","")},200))}}class m extends HTMLElement{shadow;controller=null;_config={};static get observedAttributes(){return["base-url","ws-url","user-token","api-key","title","subtitle","theme","primary-color","position","width","height","placeholder","welcome-message","avatar-url"]}constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.render(),this.initController()}disconnectedCallback(){this.controller?.disconnect()}attributeChangedCallback(e,t,a){t!==a&&this.controller&&(this.render(),this.initController())}configure(e){this._config={...this._config,...e}}getConfig(){return{baseUrl:this.getAttribute("base-url")||this._config.baseUrl||"",wsUrl:this.getAttribute("ws-url")||this._config.wsUrl,userToken:this.getAttribute("user-token")||this._config.userToken||"",apiKey:this.getAttribute("api-key")||this._config.apiKey,title:this.getAttribute("title")||this._config.title||"Chat",subtitle:this.getAttribute("subtitle")||this._config.subtitle,theme:this.getAttribute("theme")||this._config.theme||l.DEFAULT_THEME,primaryColor:this.getAttribute("primary-color")||this._config.primaryColor||l.DEFAULT_PRIMARY_COLOR,position:this.getAttribute("position")||this._config.position||l.DEFAULT_POSITION,width:Number(this.getAttribute("width"))||this._config.width||l.DEFAULT_WIDGET_WIDTH,height:Number(this.getAttribute("height"))||this._config.height||l.DEFAULT_WIDGET_HEIGHT,fontFamily:this._config.fontFamily||l.DEFAULT_FONT_FAMILY,borderRadius:this._config.borderRadius??l.DEFAULT_BORDER_RADIUS,placeholder:this.getAttribute("placeholder")||this._config.placeholder||l.DEFAULT_PLACEHOLDER,welcomeMessage:this.getAttribute("welcome-message")||this._config.welcomeMessage,avatarUrl:this.getAttribute("avatar-url")||this._config.avatarUrl,showTimestamps:this._config.showTimestamps??!0,persistConversation:this._config.persistConversation??!0,showBubble:this._config.showBubble??!0,offset:this._config.offset||l.DEFAULT_OFFSET,conversationId:this._config.conversationId,systemPromptId:this._config.systemPromptId,channel:this._config.channel,extUid:this._config.extUid,transport:this._config.transport,tiledesk:this._config.tiledesk,tiledeskIdentity:this._config.tiledeskIdentity,onMessage:this._config.onMessage,onStatusChange:this._config.onStatusChange,onError:this._config.onError,onStreamUpdate:this._config.onStreamUpdate,onConnectionStateChange:this._config.onConnectionStateChange,onTemplateMessage:this._config.onTemplateMessage}}setUploadAdapter(e){this._config.uploadAdapter=e,this.controller?.getClient().setUploadAdapter(e)}render(){const e=this.getConfig();this.shadow.innerHTML=`
2
- <style>
3
- :host {
4
- --aikaara-primary: ${e.primaryColor};
5
- --aikaara-primary-hover: ${this.darkenColor(e.primaryColor||l.DEFAULT_PRIMARY_COLOR)};
6
- --aikaara-bg: #ffffff;
7
- --aikaara-bg-secondary: #f9fafb;
8
- --aikaara-text: #1f2937;
9
- --aikaara-text-secondary: #6b7280;
10
- --aikaara-border: #e5e7eb;
11
- --aikaara-radius: ${e.borderRadius}px;
12
- --aikaara-font: ${e.fontFamily};
13
- --aikaara-panel-width: ${e.width}px;
14
- --aikaara-panel-height: ${e.height}px;
15
- --aikaara-bubble-size: 60px;
16
- --aikaara-offset-x: ${e.offset?.x??20}px;
17
- --aikaara-offset-y: ${e.offset?.y??20}px;
18
- font-family: var(--aikaara-font);
19
- position: fixed;
20
- z-index: 9999;
21
- bottom: var(--aikaara-offset-y);
22
- ${e.position==="bottom-left"?"left":"right"}: var(--aikaara-offset-x);
23
- }
24
-
25
- .aikaara-panel {
26
- width: var(--aikaara-panel-width);
27
- height: var(--aikaara-panel-height);
28
- max-height: calc(100vh - 100px);
29
- background: var(--aikaara-bg);
30
- border-radius: var(--aikaara-radius);
31
- box-shadow: 0 4px 24px rgba(0, 0, 0, 0.12);
32
- border: 1px solid var(--aikaara-border);
33
- display: flex;
34
- flex-direction: column;
35
- overflow: hidden;
36
- position: absolute;
37
- bottom: calc(var(--aikaara-bubble-size) + 16px);
38
- ${e.position==="bottom-left"?"left":"right"}: 0;
39
- transition: opacity 200ms ease, transform 200ms ease;
40
- }
41
-
42
- .aikaara-panel[hidden] {
43
- display: none;
44
- }
45
-
46
- .aikaara-panel.entering {
47
- opacity: 0;
48
- transform: translateY(8px) scale(0.98);
49
- }
50
-
51
- .aikaara-panel.visible {
52
- opacity: 1;
53
- transform: translateY(0) scale(1);
54
- }
55
-
56
- aikaara-chat-header,
57
- aikaara-message-list,
58
- aikaara-chat-input,
59
- aikaara-error-banner {
60
- display: block;
61
- }
62
-
63
- aikaara-message-list {
64
- flex: 1;
65
- overflow: scroll;
66
- min-height: 0;
67
- }
68
-
69
- aikaara-chat-input {
70
- flex-shrink: 0;
71
- }
72
-
73
- aikaara-chat-header {
74
- flex-shrink: 0;
75
- }
76
- </style>
77
-
78
- <aikaara-chat-bubble></aikaara-chat-bubble>
79
-
80
- <div class="aikaara-panel entering" hidden role="dialog" aria-label="Chat">
81
- <aikaara-chat-header
82
- title="${e.title||"Chat"}"
83
- ${e.subtitle?`subtitle="${e.subtitle}"`:""}
84
- ${e.avatarUrl?`avatar-url="${e.avatarUrl}"`:""}
85
- ></aikaara-chat-header>
86
- <aikaara-message-list></aikaara-message-list>
87
- <aikaara-chat-input placeholder="${e.placeholder||l.DEFAULT_PLACEHOLDER}"></aikaara-chat-input>
88
- <aikaara-error-banner></aikaara-error-banner>
89
- </div>
90
- `}async initController(){const e=this.getConfig();!e.baseUrl||!e.userToken||(this.controller?.disconnect(),this.controller=new S(e,this.shadow,{uploadAdapter:this._config.uploadAdapter}),await this.controller.connect())}sendUserEvent(e,t,a){this.controller?.sendUserEvent(e,t,a)}getClient(){return this.controller?.getClient()??null}darkenColor(e){try{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);return`#${(a<<16|i<<8|r).toString(16).padStart(6,"0")}`}catch{return e}}}class g extends HTMLElement{shadow;constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.render(),this.shadow.querySelector(".bubble")?.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("toggle",{bubbles:!0,composed:!0}))})}render(){this.shadow.innerHTML=`
91
- <style>
92
- .bubble {
93
- width: var(--aikaara-bubble-size, 60px);
94
- height: var(--aikaara-bubble-size, 60px);
95
- border-radius: 50%;
96
- background: var(--aikaara-primary, #6366f1);
97
- color: #ffffff;
98
- border: none;
99
- cursor: pointer;
100
- display: flex;
101
- align-items: center;
102
- justify-content: center;
103
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
104
- transition: transform 200ms ease, box-shadow 200ms ease;
105
- }
106
- .bubble:hover {
107
- transform: scale(1.05);
108
- box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
109
- }
110
- .bubble svg {
111
- width: 28px;
112
- height: 28px;
113
- }
114
- .bubble-text {
115
- font-family: var(--aikaara-font, system-ui, sans-serif);
116
- font-size: 12px;
117
- font-weight: 500;
118
- }
119
- </style>
120
- <button class="bubble" aria-label="Open chat">
121
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
122
- <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
123
- </svg>
124
- </button>
125
- `}setIcon(e){const t=this.shadow.querySelector(".bubble");t&&(t.innerHTML=e)}}class f extends HTMLElement{shadow;static get observedAttributes(){return["title","subtitle","avatar-url","status"]}constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.render(),this.bindClose()}attributeChangedCallback(){this.render(),this.bindClose()}bindClose(){this.shadow.querySelector(".close-btn")?.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("header-close",{bubbles:!0,composed:!0}))})}render(){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";this.shadow.innerHTML=`
126
- <style>
127
- .header {
128
- display: flex;
129
- align-items: center;
130
- gap: 12px;
131
- padding: 14px 16px;
132
- background: var(--aikaara-primary, #6366f1);
133
- color: #ffffff;
134
- flex-shrink: 0;
135
- }
136
- .avatar {
137
- width: 36px;
138
- height: 36px;
139
- border-radius: 50%;
140
- background: rgba(255,255,255,0.2);
141
- display: flex;
142
- align-items: center;
143
- justify-content: center;
144
- flex-shrink: 0;
145
- overflow: hidden;
146
- }
147
- .avatar img {
148
- width: 100%;
149
- height: 100%;
150
- object-fit: cover;
151
- }
152
- .avatar svg {
153
- width: 20px;
154
- height: 20px;
155
- }
156
- .info {
157
- flex: 1;
158
- min-width: 0;
159
- }
160
- .title {
161
- font-size: 15px;
162
- font-weight: 600;
163
- line-height: 1.2;
164
- display: flex;
165
- align-items: center;
166
- gap: 6px;
167
- }
168
- .status-dot {
169
- width: 8px;
170
- height: 8px;
171
- border-radius: 50%;
172
- flex-shrink: 0;
173
- }
174
- .subtitle {
175
- font-size: 12px;
176
- opacity: 0.85;
177
- white-space: nowrap;
178
- overflow: hidden;
179
- text-overflow: ellipsis;
180
- }
181
- .close-btn {
182
- background: none;
183
- border: none;
184
- color: #ffffff;
185
- cursor: pointer;
186
- padding: 4px;
187
- border-radius: 4px;
188
- display: flex;
189
- align-items: center;
190
- justify-content: center;
191
- opacity: 0.8;
192
- transition: opacity 200ms;
193
- }
194
- .close-btn:hover {
195
- opacity: 1;
196
- }
197
- .close-btn svg {
198
- width: 20px;
199
- height: 20px;
200
- }
201
- </style>
202
- <div class="header">
203
- <div class="avatar">
204
- ${a?`<img src="${a}" alt="Avatar" />`:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><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>'}
205
- </div>
206
- <div class="info">
207
- <div class="title">
208
- ${e}
209
- <span class="status-dot" style="background:${r}"></span>
210
- </div>
211
- ${t?`<div class="subtitle">${t}</div>`:""}
212
- </div>
213
- <button class="close-btn" aria-label="Close chat">
214
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
215
- <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
216
- </svg>
217
- </button>
218
- </div>
219
- `}setStatus(e){this.setAttribute("status",e)}}function d(s){let e=_(s);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(/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g,'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'),e=e.replace(/\n/g,"<br>"),e}function _(s){const e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return s.replace(/[&<>"']/g,t=>e[t])}const $=new Set(["p","br","strong","em","code","pre","a","ul","ol","li","blockquote","h1","h2","h3","h4","h5","h6","span","div"]),H={a:new Set(["href","target","rel"]),code:new Set(["class"]),pre:new Set(["class"]),span:new Set(["class"]),div:new Set(["class"])};function c(s){const e=document.createElement("template");return e.innerHTML=s,x(e.content),e.innerHTML}function x(s){const e=Array.from(s.childNodes);for(const t of e)if(t.nodeType===Node.ELEMENT_NODE){const a=t,i=a.tagName.toLowerCase();if(!$.has(i)){const n=document.createTextNode(a.textContent||"");s.replaceChild(n,t);continue}const r=H[i]||new Set,o=Array.from(a.attributes);for(const n of o)r.has(n.name)||a.removeAttribute(n.name);if(a.hasAttribute("href")){const n=a.getAttribute("href")||"";!n.startsWith("http://")&&!n.startsWith("https://")&&!n.startsWith("/")&&a.removeAttribute("href")}x(t)}}class k extends HTMLElement{shadow;container;welcomeMessage="";showTimestamps=!0;constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.shadow.innerHTML=`
220
- <style>
221
- :host {
222
- display: flex;
223
- flex-direction: column;
224
- min-height: 0;
225
- }
226
- .message-list {
227
- flex: 1;
228
- overflow-y: auto;
229
- padding: 16px;
230
- display: flex;
231
- flex-direction: column;
232
- gap: 8px;
233
- scroll-behavior: smooth;
234
- }
235
- .message-list::-webkit-scrollbar { width: 6px; }
236
- .message-list::-webkit-scrollbar-track { background: transparent; }
237
- .message-list::-webkit-scrollbar-thumb { background: var(--aikaara-border, #e5e7eb); border-radius: 3px; }
238
- .message-wrap { display: flex; flex-direction: column; }
239
- .message-wrap.user { align-items: flex-end; }
240
- .message-wrap.assistant,
241
- .message-wrap.agent,
242
- .message-wrap.system { align-items: flex-start; }
243
- .message-wrap.system .bubble {
244
- background: transparent;
245
- color: var(--aikaara-text-secondary, #6b7280);
246
- font-size: 12px;
247
- font-style: italic;
248
- padding: 4px 0;
249
- }
250
- .attachments {
251
- display: flex;
252
- flex-direction: column;
253
- gap: 4px;
254
- margin-top: 6px;
255
- }
256
- .attachment {
257
- display: inline-flex;
258
- align-items: center;
259
- gap: 6px;
260
- padding: 6px 10px;
261
- background: rgba(0,0,0,0.05);
262
- border-radius: 8px;
263
- font-size: 12px;
264
- color: inherit;
265
- text-decoration: none;
266
- }
267
- .attachment:hover { background: rgba(0,0,0,0.08); }
268
- .status-tick {
269
- font-size: 10px;
270
- margin-left: 4px;
271
- color: var(--aikaara-text-secondary, #6b7280);
272
- }
273
- .status-tick.read { color: var(--aikaara-primary, #6366f1); }
274
- aikaara-template-renderer { display: block; margin-top: 6px; }
275
- .bubble {
276
- max-width: 85%;
277
- padding: 10px 14px;
278
- border-radius: var(--aikaara-radius, 12px);
279
- font-size: 14px;
280
- line-height: 1.5;
281
- word-wrap: break-word;
282
- overflow-wrap: break-word;
283
- }
284
- .bubble.user {
285
- background: var(--aikaara-primary, #6366f1);
286
- color: #ffffff;
287
- border-bottom-right-radius: 4px;
288
- }
289
- .bubble.assistant {
290
- background: var(--aikaara-bg-secondary, #f9fafb);
291
- color: var(--aikaara-text, #1f2937);
292
- border-bottom-left-radius: 4px;
293
- }
294
- .bubble pre {
295
- background: rgba(0,0,0,0.06);
296
- padding: 8px 12px;
297
- border-radius: 6px;
298
- overflow-x: auto;
299
- font-size: 13px;
300
- margin: 8px 0;
301
- }
302
- .bubble code {
303
- font-family: 'SF Mono', 'Fira Code', monospace;
304
- font-size: 13px;
305
- }
306
- .bubble.assistant code:not(pre code) {
307
- background: rgba(0,0,0,0.06);
308
- padding: 2px 4px;
309
- border-radius: 3px;
310
- }
311
- .bubble a { color: inherit; text-decoration: underline; }
312
- .timestamp {
313
- font-size: 11px;
314
- color: var(--aikaara-text-secondary, #6b7280);
315
- margin-top: 2px;
316
- padding: 0 4px;
317
- }
318
- .welcome {
319
- text-align: center;
320
- color: var(--aikaara-text-secondary, #6b7280);
321
- font-size: 14px;
322
- padding: 24px 16px;
323
- }
324
- .streaming-cursor::after {
325
- content: '\\25CF';
326
- animation: blink 1s infinite;
327
- margin-left: 2px;
328
- font-size: 10px;
329
- vertical-align: middle;
330
- }
331
- @keyframes blink {
332
- 0%, 100% { opacity: 1; }
333
- 50% { opacity: 0; }
334
- }
335
- .typing-indicator {
336
- display: flex;
337
- align-items: center;
338
- gap: 4px;
339
- padding: 10px 14px;
340
- align-self: flex-start;
341
- background: var(--aikaara-bg-secondary, #f9fafb);
342
- border-radius: var(--aikaara-radius, 12px);
343
- border-bottom-left-radius: 4px;
344
- }
345
- .typing-indicator .dot {
346
- width: 6px;
347
- height: 6px;
348
- border-radius: 50%;
349
- background: var(--aikaara-text-secondary, #6b7280);
350
- animation: typing-bounce 1.4s infinite ease-in-out;
351
- }
352
- .typing-indicator .dot:nth-child(1) { animation-delay: 0ms; }
353
- .typing-indicator .dot:nth-child(2) { animation-delay: 200ms; }
354
- .typing-indicator .dot:nth-child(3) { animation-delay: 400ms; }
355
- @keyframes typing-bounce {
356
- 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
357
- 30% { transform: translateY(-4px); opacity: 1; }
358
- }
359
- </style>
360
- <div class="message-list"></div>
361
- `,this.container=this.shadow.querySelector(".message-list"),this.welcomeMessage&&this.renderMessages([])}setWelcomeMessage(e){this.welcomeMessage=e}setShowTimestamps(e){this.showTimestamps=e}renderMessages(e){if(this.container){if(this.container.innerHTML="",e.length===0&&this.welcomeMessage){this.container.innerHTML=`<div class="welcome">${c(d(this.welcomeMessage))}</div>`;return}for(const t of e)this.appendMessageElement(t);this.scrollToBottom()}}addMessage(e){const t=this.container.querySelector(".welcome");t&&t.remove(),this.appendMessageElement(e),this.scrollToBottom()}updateStreamingContent(e){const t=this.container.querySelector('[data-streaming="true"] .bubble');t&&(t.innerHTML=c(d(e)),t.classList.add("streaming-cursor"),this.scrollToBottom())}finalizeStreaming(){const e=this.container.querySelector('[data-streaming="true"]');e&&(e.removeAttribute("data-streaming"),e.querySelector(".bubble")?.classList.remove("streaming-cursor"))}showTypingIndicator(){this.removeTypingIndicator();const e=document.createElement("div");e.classList.add("typing-indicator"),e.setAttribute("data-typing","true"),e.innerHTML='<span class="dot"></span><span class="dot"></span><span class="dot"></span>',this.container.appendChild(e),this.scrollToBottom()}removeTypingIndicator(){this.container.querySelector('[data-typing="true"]')?.remove()}appendMessageElement(e){const t=document.createElement("div");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;const a=document.createElement("div");if(a.classList.add("bubble",e.role),e.role==="user"?a.textContent=e.content:(a.innerHTML=c(d(e.content||"")),e.status==="streaming"&&a.classList.add("streaming-cursor")),e.template?.contentType){const i=document.createElement("aikaara-template-renderer");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)}if(e.attachments?.length){const i=document.createElement("div");i.classList.add("attachments");for(const r of e.attachments){const o=document.createElement("a");o.classList.add("attachment"),o.href=r.fileUrl,o.target="_blank",o.rel="noopener noreferrer",o.textContent=`📎 ${r.fileName}`,i.appendChild(o)}a.appendChild(i)}if(t.appendChild(a),this.showTimestamps&&e.createdAt||e.role==="user"&&e.status){const i=document.createElement("div");if(i.classList.add("timestamp"),this.showTimestamps&&e.createdAt&&(i.textContent=this.formatTime(e.createdAt)),e.role==="user"&&e.status){const r=document.createElement("span");r.classList.add("status-tick"),e.status==="read"&&r.classList.add("read"),r.textContent={sending:" ○",sent:" ✓",delivered:" ✓✓",read:" ✓✓"}[e.status]??"",i.appendChild(r)}t.appendChild(i)}this.container.appendChild(t)}upsertMessage(e){const t=this.findRenderedMessage(e);t&&t.remove(),this.appendMessageElement(e),this.scrollToBottom()}findRenderedMessage(e){if(e.externalId){const t=this.container.querySelector(`[data-external-id="${CSS.escape(e.externalId)}"]`);if(t)return t}return this.container.querySelector(`[data-message-id="${CSS.escape(e.id)}"]`)}scrollToBottom(){requestAnimationFrame(()=>{this.container.scrollTop=this.container.scrollHeight})}formatTime(e){try{return new Date(e).toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"})}catch{return""}}}class y extends HTMLElement{shadow;templatePayload=null;attachments=[];static get observedAttributes(){return["role","content","timestamp","content-type","template-id","inner-message","message-id","status"]}constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}setTemplatePayload(e){this.templatePayload=e,this.render()}setAttachments(e){this.attachments=e,this.render()}render(){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")||"",p=e==="user"?document.createTextNode(t).textContent||"":c(d(t)),u=e==="user"&&i,E=i==="sending"?"○":i==="sent"?"✓":i==="delivered"||i==="read"?"✓✓":"";this.shadow.innerHTML=`
362
- <style>
363
- :host { display: flex; flex-direction: column; }
364
- :host([role="user"]) { align-items: flex-end; }
365
- :host([role="assistant"]),
366
- :host([role="agent"]),
367
- :host([role="system"]) { align-items: flex-start; }
368
- .bubble {
369
- max-width: 85%;
370
- padding: 10px 14px;
371
- border-radius: var(--aikaara-radius, 12px);
372
- font-size: 14px;
373
- line-height: 1.5;
374
- word-wrap: break-word;
375
- }
376
- .bubble.user {
377
- background: var(--aikaara-primary, #6366f1);
378
- color: #fff;
379
- border-bottom-right-radius: 4px;
380
- }
381
- .bubble.assistant, .bubble.agent {
382
- background: var(--aikaara-bg-secondary, #f9fafb);
383
- color: var(--aikaara-text, #1f2937);
384
- border-bottom-left-radius: 4px;
385
- }
386
- .bubble.system {
387
- background: transparent;
388
- color: var(--aikaara-text-secondary, #6b7280);
389
- font-size: 12px;
390
- font-style: italic;
391
- }
392
- .timestamp {
393
- font-size: 11px;
394
- color: var(--aikaara-text-secondary, #6b7280);
395
- margin-top: 2px;
396
- padding: 0 4px;
397
- }
398
- .status {
399
- font-size: 10px;
400
- color: ${i==="read"?"var(--aikaara-primary, #6366f1)":"var(--aikaara-text-secondary, #6b7280)"};
401
- margin-left: 4px;
402
- }
403
- .attachments {
404
- display: flex;
405
- flex-direction: column;
406
- gap: 6px;
407
- margin-top: 8px;
408
- }
409
- .attachment {
410
- display: inline-flex;
411
- align-items: center;
412
- gap: 6px;
413
- padding: 6px 10px;
414
- background: rgba(0,0,0,0.05);
415
- border-radius: 8px;
416
- font-size: 12px;
417
- color: inherit;
418
- text-decoration: none;
419
- max-width: 100%;
420
- }
421
- .attachment:hover { background: rgba(0,0,0,0.08); }
422
- aikaara-template-renderer { display: block; margin-top: 6px; }
423
- </style>
424
- <div class="bubble ${e}">
425
- <div class="content">${p}</div>
426
- ${r?`<aikaara-template-renderer
427
- content-type="${r}"
428
- template-id="${o}"
429
- inner-message="${b(n)}"
430
- ></aikaara-template-renderer>`:""}
431
- ${this.renderAttachments()}
432
- </div>
433
- ${a||u?`
434
- <div class="timestamp">
435
- ${a}${u?`<span class="status">${E}</span>`:""}
436
- </div>
437
- `:""}
438
- `;const h=this.shadow.querySelector("aikaara-template-renderer");h&&this.templatePayload!==null&&h.setPayload(this.templatePayload,n),h&&h.addEventListener("template-action",M=>{this.dispatchEvent(new CustomEvent("message-action",{detail:M.detail,bubbles:!0,composed:!0}))})}renderAttachments(){return this.attachments.length?`<div class="attachments">${this.attachments.map(t=>`<a class="attachment" href="${b(t.fileUrl)}" target="_blank" rel="noopener noreferrer">
439
- 📎 ${z(t.fileName)}
440
- </a>`).join("")}</div>`:""}}function b(s){return String(s).replace(/[&<>"']/g,e=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[e])}function z(s){return String(s).replace(/[&<>]/g,e=>({"&":"&amp;","<":"&lt;",">":"&gt;"})[e])}class v extends HTMLElement{shadow;textarea;sendBtn;_disabled=!1;constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){const e=this.getAttribute("placeholder")||"Type a message...";this.shadow.innerHTML=`
441
- <style>
442
- .input-container {
443
- display: flex;
444
- align-items: flex-end;
445
- gap: 8px;
446
- padding: 12px 16px;
447
- border-top: 1px solid var(--aikaara-border, #e5e7eb);
448
- background: var(--aikaara-bg, #ffffff);
449
- }
450
- textarea {
451
- flex: 1;
452
- resize: none;
453
- border: 1px solid var(--aikaara-border, #e5e7eb);
454
- border-radius: 8px;
455
- padding: 10px 12px;
456
- font-family: var(--aikaara-font, system-ui, sans-serif);
457
- font-size: 14px;
458
- color: var(--aikaara-text, #1f2937);
459
- background: var(--aikaara-bg, #ffffff);
460
- outline: none;
461
- min-height: 40px;
462
- max-height: 120px;
463
- line-height: 1.4;
464
- transition: border-color 200ms ease;
465
- }
466
- textarea:focus {
467
- border-color: var(--aikaara-primary, #6366f1);
468
- }
469
- textarea::placeholder {
470
- color: var(--aikaara-text-secondary, #6b7280);
471
- }
472
- .send-btn {
473
- width: 40px;
474
- height: 40px;
475
- border: none;
476
- border-radius: 50%;
477
- background: var(--aikaara-primary, #6366f1);
478
- color: #ffffff;
479
- cursor: pointer;
480
- display: flex;
481
- align-items: center;
482
- justify-content: center;
483
- flex-shrink: 0;
484
- transition: background 200ms, opacity 200ms;
485
- }
486
- .send-btn:hover { background: var(--aikaara-primary-hover, #4f46e5); }
487
- .send-btn:disabled { opacity: 0.5; cursor: not-allowed; }
488
- .send-btn svg { width: 18px; height: 18px; }
489
- </style>
490
- <div class="input-container">
491
- <textarea rows="1" placeholder="${e}"></textarea>
492
- <button class="send-btn" aria-label="Send message" disabled>
493
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
494
- <line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/>
495
- </svg>
496
- </button>
497
- </div>
498
- `,this.textarea=this.shadow.querySelector("textarea"),this.sendBtn=this.shadow.querySelector(".send-btn"),this.textarea.addEventListener("input",()=>{this.autoGrow(),this.sendBtn.disabled=this._disabled||!this.textarea.value.trim()}),this.textarea.addEventListener("keydown",t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),this.handleSend())}),this.sendBtn.addEventListener("click",()=>this.handleSend())}set disabled(e){this._disabled=e,this.textarea&&(this.textarea.disabled=e),this.sendBtn&&(this.sendBtn.disabled=e||!this.textarea?.value.trim())}get disabled(){return this._disabled}focus(){this.textarea?.focus()}clear(){this.textarea&&(this.textarea.value="",this.textarea.style.height="auto",this.sendBtn.disabled=!0)}handleSend(){const e=this.textarea.value.trim();!e||this._disabled||(this.dispatchEvent(new CustomEvent("send",{detail:{content:e},bubbles:!0,composed:!0})),this.clear(),this.textarea.focus())}autoGrow(){this.textarea.style.height="auto",this.textarea.style.height=Math.min(this.textarea.scrollHeight,120)+"px"}}class w extends HTMLElement{shadow;constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.shadow.innerHTML=`
499
- <style>
500
- :host { display: none; }
501
- :host([visible]) { display: block; }
502
- .typing {
503
- display: flex;
504
- align-items: center;
505
- gap: 4px;
506
- padding: 10px 14px;
507
- background: var(--aikaara-bg-secondary, #f9fafb);
508
- border-radius: var(--aikaara-radius, 12px);
509
- border-bottom-left-radius: 4px;
510
- width: fit-content;
511
- }
512
- .dot {
513
- width: 6px;
514
- height: 6px;
515
- border-radius: 50%;
516
- background: var(--aikaara-text-secondary, #6b7280);
517
- animation: bounce 1.4s infinite ease-in-out;
518
- }
519
- .dot:nth-child(1) { animation-delay: 0ms; }
520
- .dot:nth-child(2) { animation-delay: 200ms; }
521
- .dot:nth-child(3) { animation-delay: 400ms; }
522
- @keyframes bounce {
523
- 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
524
- 30% { transform: translateY(-4px); opacity: 1; }
525
- }
526
- </style>
527
- <div class="typing">
528
- <span class="dot"></span>
529
- <span class="dot"></span>
530
- <span class="dot"></span>
531
- </div>
532
- `}show(){this.setAttribute("visible","")}hide(){this.removeAttribute("visible")}}class C extends HTMLElement{shadow;bubble;constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.shadow.innerHTML=`
533
- <style>
534
- :host {
535
- display: flex;
536
- flex-direction: column;
537
- align-items: flex-start;
538
- }
539
- .bubble {
540
- max-width: 85%;
541
- padding: 10px 14px;
542
- border-radius: var(--aikaara-radius, 12px);
543
- border-bottom-left-radius: 4px;
544
- background: var(--aikaara-bg-secondary, #f9fafb);
545
- color: var(--aikaara-text, #1f2937);
546
- font-size: 14px;
547
- line-height: 1.5;
548
- word-wrap: break-word;
549
- min-height: 20px;
550
- }
551
- .bubble pre {
552
- background: rgba(0,0,0,0.06);
553
- padding: 8px 12px;
554
- border-radius: 6px;
555
- overflow-x: auto;
556
- font-size: 13px;
557
- margin: 8px 0;
558
- }
559
- .bubble code {
560
- font-family: 'SF Mono', 'Fira Code', monospace;
561
- font-size: 13px;
562
- }
563
- .bubble code:not(pre code) {
564
- background: rgba(0,0,0,0.06);
565
- padding: 2px 4px;
566
- border-radius: 3px;
567
- }
568
- .cursor::after {
569
- content: '\\25CF';
570
- animation: blink 1s infinite;
571
- margin-left: 2px;
572
- font-size: 10px;
573
- vertical-align: middle;
574
- }
575
- @keyframes blink {
576
- 0%, 100% { opacity: 1; }
577
- 50% { opacity: 0; }
578
- }
579
- </style>
580
- <div class="bubble cursor"></div>
581
- `,this.bubble=this.shadow.querySelector(".bubble")}updateContent(e){this.bubble&&(this.bubble.innerHTML=c(d(e)),this.bubble.classList.add("cursor"))}finalize(){this.bubble?.classList.remove("cursor")}}class A extends HTMLElement{shadow;container;dismissTimer=null;constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.shadow.innerHTML=`
582
- <style>
583
- .banner {
584
- display: none;
585
- padding: 8px 16px;
586
- background: #fef2f2;
587
- color: #dc2626;
588
- font-size: 13px;
589
- text-align: center;
590
- border-top: 1px solid #fecaca;
591
- }
592
- .banner.visible {
593
- display: block;
594
- }
595
- .dismiss {
596
- background: none;
597
- border: none;
598
- color: #dc2626;
599
- cursor: pointer;
600
- font-size: 12px;
601
- text-decoration: underline;
602
- margin-left: 8px;
603
- }
604
- </style>
605
- <div class="banner">
606
- <span class="message"></span>
607
- <button class="dismiss">Dismiss</button>
608
- </div>
609
- `,this.container=this.shadow.querySelector(".banner"),this.shadow.querySelector(".dismiss")?.addEventListener("click",()=>this.hide())}show(e,t){const a=this.container.querySelector(".message");a&&(a.textContent=e),this.container.classList.add("visible"),this.dismissTimer&&clearTimeout(this.dismissTimer),t&&(this.dismissTimer=setTimeout(()=>this.hide(),t))}hide(){this.container.classList.remove("visible"),this.dismissTimer&&(clearTimeout(this.dismissTimer),this.dismissTimer=null)}}class T extends HTMLElement{shadow;payloadData=null;innerMessage="";static get observedAttributes(){return["content-type","template-id","inner-message"]}constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}setPayload(e,t){this.payloadData=e,t!==void 0&&(this.innerMessage=t),this.render()}render(){const e=this.getAttribute("content-type")??"",t=this.getAttribute("template-id")??"",a=this.getAttribute("inner-message")??this.innerMessage;this.shadow.innerHTML=`
610
- <style>
611
- :host { display: block; }
612
- .inner { font-size: 14px; line-height: 1.5; color: var(--aikaara-text, #1f2937); }
613
- .placeholder {
614
- font-size: 12px;
615
- color: var(--aikaara-text-secondary, #6b7280);
616
- padding: 6px 0;
617
- }
618
- </style>
619
- ${a?'<div class="inner"></div>':""}
620
- <slot></slot>
621
- `;const i=this.shadow.querySelector(".inner");if(i&&a&&(i.textContent=a),!e)return;const r=t?`aikaara-template-${t}`:`aikaara-template-${e}`;if(customElements.get(r)){const o=this.querySelector(r);if(o){o.setPayload?.(this.payloadData);return}const n=document.createElement(r);n.setPayload?.(this.payloadData),n.addEventListener("template-action",p=>{this.dispatchEvent(new CustomEvent("template-action",{detail:p.detail,bubbles:!0,composed:!0}))}),this.appendChild(n)}}}function L(){const s=[["aikaara-chat-widget",m],["aikaara-chat-bubble",g],["aikaara-chat-header",f],["aikaara-message-list",k],["aikaara-message-bubble",y],["aikaara-chat-input",v],["aikaara-typing-indicator",w],["aikaara-streaming-message",C],["aikaara-error-banner",A],["aikaara-template-renderer",T]];for(const[e,t]of s)customElements.get(e)||customElements.define(e,t)}L();exports.AikaaraChatBubble=g;exports.AikaaraChatHeader=f;exports.AikaaraChatInput=v;exports.AikaaraChatWidget=m;exports.AikaaraErrorBanner=A;exports.AikaaraMessageBubble=y;exports.AikaaraMessageList=k;exports.AikaaraStreamingMessage=C;exports.AikaaraTemplateRenderer=T;exports.AikaaraTypingIndicator=w;exports.registerComponents=L;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./ui-B0-Np9Dn.cjs");exports.AikaaraChatBubble=a.AikaaraChatBubble;exports.AikaaraChatHeader=a.AikaaraChatHeader;exports.AikaaraChatInput=a.AikaaraChatInput;exports.AikaaraChatWidget=a.AikaaraChatWidget;exports.AikaaraErrorBanner=a.AikaaraErrorBanner;exports.AikaaraMessageBubble=a.AikaaraMessageBubble;exports.AikaaraMessageList=a.AikaaraMessageList;exports.AikaaraModalAction=a.AikaaraModalAction;exports.AikaaraOptionList=a.AikaaraOptionList;exports.AikaaraStreamingMessage=a.AikaaraStreamingMessage;exports.AikaaraSubmitAction=a.AikaaraSubmitAction;exports.AikaaraSystemPill=a.AikaaraSystemPill;exports.AikaaraTemplateRenderer=a.AikaaraTemplateRenderer;exports.AikaaraTypingIndicator=a.AikaaraTypingIndicator;exports.registerComponents=a.registerComponents;