@aikaara/chat-sdk 0.2.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,528 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./AikaaraChatClient-ChZ2bL9f.cjs");class w{client;panel;bubble;header;messageList;input;errorBanner;isOpen=!1;constructor(e,t){this.client=new r.AikaaraChatClient(e),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)})}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 c 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||r.DEFAULT_THEME,primaryColor:this.getAttribute("primary-color")||this._config.primaryColor||r.DEFAULT_PRIMARY_COLOR,position:this.getAttribute("position")||this._config.position||r.DEFAULT_POSITION,width:Number(this.getAttribute("width"))||this._config.width||r.DEFAULT_WIDGET_WIDTH,height:Number(this.getAttribute("height"))||this._config.height||r.DEFAULT_WIDGET_HEIGHT,fontFamily:this._config.fontFamily||r.DEFAULT_FONT_FAMILY,borderRadius:this._config.borderRadius??r.DEFAULT_BORDER_RADIUS,placeholder:this.getAttribute("placeholder")||this._config.placeholder||r.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||r.DEFAULT_OFFSET,conversationId:this._config.conversationId,systemPromptId:this._config.systemPromptId,channel:this._config.channel,extUid:this._config.extUid,onMessage:this._config.onMessage,onStatusChange:this._config.onStatusChange,onError:this._config.onError,onStreamUpdate:this._config.onStreamUpdate,onConnectionStateChange:this._config.onConnectionStateChange}}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||r.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||r.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 w(e,this.shadow),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),s=Math.max(0,(t>>8&255)-20),o=Math.max(0,(t&255)-20);return`#${(a<<16|s<<8|o).toString(16).padStart(6,"0")}`}catch{return e}}}class h 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 b 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"),s=this.getAttribute("status")||"connected",o=s==="connected"?"#10b981":s==="connecting"||s==="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:${o}"></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 l(i){let e=C(i);return e=e.replace(/```(\w*)\n([\s\S]*?)```/g,(t,a,s)=>`<pre><code>${s.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 C(i){const e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return i.replace(/[&<>"']/g,t=>e[t])}const T=new Set(["p","br","strong","em","code","pre","a","ul","ol","li","blockquote","h1","h2","h3","h4","h5","h6","span","div"]),L={a:new Set(["href","target","rel"]),code:new Set(["class"]),pre:new Set(["class"]),span:new Set(["class"]),div:new Set(["class"])};function d(i){const e=document.createElement("template");return e.innerHTML=i,p(e.content),e.innerHTML}function p(i){const e=Array.from(i.childNodes);for(const t of e)if(t.nodeType===Node.ELEMENT_NODE){const a=t,s=a.tagName.toLowerCase();if(!T.has(s)){const n=document.createTextNode(a.textContent||"");i.replaceChild(n,t);continue}const o=L[s]||new Set,v=Array.from(a.attributes);for(const n of v)o.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")}p(t)}}class u 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 { align-items: flex-start; }
241
- .bubble {
242
- max-width: 85%;
243
- padding: 10px 14px;
244
- border-radius: var(--aikaara-radius, 12px);
245
- font-size: 14px;
246
- line-height: 1.5;
247
- word-wrap: break-word;
248
- overflow-wrap: break-word;
249
- }
250
- .bubble.user {
251
- background: var(--aikaara-primary, #6366f1);
252
- color: #ffffff;
253
- border-bottom-right-radius: 4px;
254
- }
255
- .bubble.assistant {
256
- background: var(--aikaara-bg-secondary, #f9fafb);
257
- color: var(--aikaara-text, #1f2937);
258
- border-bottom-left-radius: 4px;
259
- }
260
- .bubble pre {
261
- background: rgba(0,0,0,0.06);
262
- padding: 8px 12px;
263
- border-radius: 6px;
264
- overflow-x: auto;
265
- font-size: 13px;
266
- margin: 8px 0;
267
- }
268
- .bubble code {
269
- font-family: 'SF Mono', 'Fira Code', monospace;
270
- font-size: 13px;
271
- }
272
- .bubble.assistant code:not(pre code) {
273
- background: rgba(0,0,0,0.06);
274
- padding: 2px 4px;
275
- border-radius: 3px;
276
- }
277
- .bubble a { color: inherit; text-decoration: underline; }
278
- .timestamp {
279
- font-size: 11px;
280
- color: var(--aikaara-text-secondary, #6b7280);
281
- margin-top: 2px;
282
- padding: 0 4px;
283
- }
284
- .welcome {
285
- text-align: center;
286
- color: var(--aikaara-text-secondary, #6b7280);
287
- font-size: 14px;
288
- padding: 24px 16px;
289
- }
290
- .streaming-cursor::after {
291
- content: '\\25CF';
292
- animation: blink 1s infinite;
293
- margin-left: 2px;
294
- font-size: 10px;
295
- vertical-align: middle;
296
- }
297
- @keyframes blink {
298
- 0%, 100% { opacity: 1; }
299
- 50% { opacity: 0; }
300
- }
301
- .typing-indicator {
302
- display: flex;
303
- align-items: center;
304
- gap: 4px;
305
- padding: 10px 14px;
306
- align-self: flex-start;
307
- background: var(--aikaara-bg-secondary, #f9fafb);
308
- border-radius: var(--aikaara-radius, 12px);
309
- border-bottom-left-radius: 4px;
310
- }
311
- .typing-indicator .dot {
312
- width: 6px;
313
- height: 6px;
314
- border-radius: 50%;
315
- background: var(--aikaara-text-secondary, #6b7280);
316
- animation: typing-bounce 1.4s infinite ease-in-out;
317
- }
318
- .typing-indicator .dot:nth-child(1) { animation-delay: 0ms; }
319
- .typing-indicator .dot:nth-child(2) { animation-delay: 200ms; }
320
- .typing-indicator .dot:nth-child(3) { animation-delay: 400ms; }
321
- @keyframes typing-bounce {
322
- 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
323
- 30% { transform: translateY(-4px); opacity: 1; }
324
- }
325
- </style>
326
- <div class="message-list"></div>
327
- `,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">${d(l(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=d(l(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");const a=document.createElement("div");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")),t.appendChild(a),this.showTimestamps&&e.createdAt){const s=document.createElement("div");s.classList.add("timestamp"),s.textContent=this.formatTime(e.createdAt),t.appendChild(s)}this.container.appendChild(t)}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 g extends HTMLElement{shadow;static get observedAttributes(){return["role","content","timestamp"]}constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}render(){const e=this.getAttribute("role")||"user",t=this.getAttribute("content")||"",a=this.getAttribute("timestamp")||"",s=e==="user"?document.createTextNode(t).textContent||"":d(l(t));this.shadow.innerHTML=`
328
- <style>
329
- :host { display: flex; flex-direction: column; }
330
- :host([role="user"]) { align-items: flex-end; }
331
- :host([role="assistant"]) { align-items: flex-start; }
332
- .bubble {
333
- max-width: 85%;
334
- padding: 10px 14px;
335
- border-radius: var(--aikaara-radius, 12px);
336
- font-size: 14px;
337
- line-height: 1.5;
338
- word-wrap: break-word;
339
- }
340
- .bubble.user {
341
- background: var(--aikaara-primary, #6366f1);
342
- color: #fff;
343
- border-bottom-right-radius: 4px;
344
- }
345
- .bubble.assistant {
346
- background: var(--aikaara-bg-secondary, #f9fafb);
347
- color: var(--aikaara-text, #1f2937);
348
- border-bottom-left-radius: 4px;
349
- }
350
- .timestamp {
351
- font-size: 11px;
352
- color: var(--aikaara-text-secondary, #6b7280);
353
- margin-top: 2px;
354
- padding: 0 4px;
355
- }
356
- </style>
357
- <div class="bubble ${e}">${s}</div>
358
- ${a?`<div class="timestamp">${a}</div>`:""}
359
- `}}class m 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=`
360
- <style>
361
- .input-container {
362
- display: flex;
363
- align-items: flex-end;
364
- gap: 8px;
365
- padding: 12px 16px;
366
- border-top: 1px solid var(--aikaara-border, #e5e7eb);
367
- background: var(--aikaara-bg, #ffffff);
368
- }
369
- textarea {
370
- flex: 1;
371
- resize: none;
372
- border: 1px solid var(--aikaara-border, #e5e7eb);
373
- border-radius: 8px;
374
- padding: 10px 12px;
375
- font-family: var(--aikaara-font, system-ui, sans-serif);
376
- font-size: 14px;
377
- color: var(--aikaara-text, #1f2937);
378
- background: var(--aikaara-bg, #ffffff);
379
- outline: none;
380
- min-height: 40px;
381
- max-height: 120px;
382
- line-height: 1.4;
383
- transition: border-color 200ms ease;
384
- }
385
- textarea:focus {
386
- border-color: var(--aikaara-primary, #6366f1);
387
- }
388
- textarea::placeholder {
389
- color: var(--aikaara-text-secondary, #6b7280);
390
- }
391
- .send-btn {
392
- width: 40px;
393
- height: 40px;
394
- border: none;
395
- border-radius: 50%;
396
- background: var(--aikaara-primary, #6366f1);
397
- color: #ffffff;
398
- cursor: pointer;
399
- display: flex;
400
- align-items: center;
401
- justify-content: center;
402
- flex-shrink: 0;
403
- transition: background 200ms, opacity 200ms;
404
- }
405
- .send-btn:hover { background: var(--aikaara-primary-hover, #4f46e5); }
406
- .send-btn:disabled { opacity: 0.5; cursor: not-allowed; }
407
- .send-btn svg { width: 18px; height: 18px; }
408
- </style>
409
- <div class="input-container">
410
- <textarea rows="1" placeholder="${e}"></textarea>
411
- <button class="send-btn" aria-label="Send message" disabled>
412
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
413
- <line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/>
414
- </svg>
415
- </button>
416
- </div>
417
- `,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 f extends HTMLElement{shadow;constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.shadow.innerHTML=`
418
- <style>
419
- :host { display: none; }
420
- :host([visible]) { display: block; }
421
- .typing {
422
- display: flex;
423
- align-items: center;
424
- gap: 4px;
425
- padding: 10px 14px;
426
- background: var(--aikaara-bg-secondary, #f9fafb);
427
- border-radius: var(--aikaara-radius, 12px);
428
- border-bottom-left-radius: 4px;
429
- width: fit-content;
430
- }
431
- .dot {
432
- width: 6px;
433
- height: 6px;
434
- border-radius: 50%;
435
- background: var(--aikaara-text-secondary, #6b7280);
436
- animation: bounce 1.4s infinite ease-in-out;
437
- }
438
- .dot:nth-child(1) { animation-delay: 0ms; }
439
- .dot:nth-child(2) { animation-delay: 200ms; }
440
- .dot:nth-child(3) { animation-delay: 400ms; }
441
- @keyframes bounce {
442
- 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
443
- 30% { transform: translateY(-4px); opacity: 1; }
444
- }
445
- </style>
446
- <div class="typing">
447
- <span class="dot"></span>
448
- <span class="dot"></span>
449
- <span class="dot"></span>
450
- </div>
451
- `}show(){this.setAttribute("visible","")}hide(){this.removeAttribute("visible")}}class x extends HTMLElement{shadow;bubble;constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.shadow.innerHTML=`
452
- <style>
453
- :host {
454
- display: flex;
455
- flex-direction: column;
456
- align-items: flex-start;
457
- }
458
- .bubble {
459
- max-width: 85%;
460
- padding: 10px 14px;
461
- border-radius: var(--aikaara-radius, 12px);
462
- border-bottom-left-radius: 4px;
463
- background: var(--aikaara-bg-secondary, #f9fafb);
464
- color: var(--aikaara-text, #1f2937);
465
- font-size: 14px;
466
- line-height: 1.5;
467
- word-wrap: break-word;
468
- min-height: 20px;
469
- }
470
- .bubble pre {
471
- background: rgba(0,0,0,0.06);
472
- padding: 8px 12px;
473
- border-radius: 6px;
474
- overflow-x: auto;
475
- font-size: 13px;
476
- margin: 8px 0;
477
- }
478
- .bubble code {
479
- font-family: 'SF Mono', 'Fira Code', monospace;
480
- font-size: 13px;
481
- }
482
- .bubble code:not(pre code) {
483
- background: rgba(0,0,0,0.06);
484
- padding: 2px 4px;
485
- border-radius: 3px;
486
- }
487
- .cursor::after {
488
- content: '\\25CF';
489
- animation: blink 1s infinite;
490
- margin-left: 2px;
491
- font-size: 10px;
492
- vertical-align: middle;
493
- }
494
- @keyframes blink {
495
- 0%, 100% { opacity: 1; }
496
- 50% { opacity: 0; }
497
- }
498
- </style>
499
- <div class="bubble cursor"></div>
500
- `,this.bubble=this.shadow.querySelector(".bubble")}updateContent(e){this.bubble&&(this.bubble.innerHTML=d(l(e)),this.bubble.classList.add("cursor"))}finalize(){this.bubble?.classList.remove("cursor")}}class k extends HTMLElement{shadow;container;dismissTimer=null;constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.shadow.innerHTML=`
501
- <style>
502
- .banner {
503
- display: none;
504
- padding: 8px 16px;
505
- background: #fef2f2;
506
- color: #dc2626;
507
- font-size: 13px;
508
- text-align: center;
509
- border-top: 1px solid #fecaca;
510
- }
511
- .banner.visible {
512
- display: block;
513
- }
514
- .dismiss {
515
- background: none;
516
- border: none;
517
- color: #dc2626;
518
- cursor: pointer;
519
- font-size: 12px;
520
- text-decoration: underline;
521
- margin-left: 8px;
522
- }
523
- </style>
524
- <div class="banner">
525
- <span class="message"></span>
526
- <button class="dismiss">Dismiss</button>
527
- </div>
528
- `,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)}}function y(){const i=[["aikaara-chat-widget",c],["aikaara-chat-bubble",h],["aikaara-chat-header",b],["aikaara-message-list",u],["aikaara-message-bubble",g],["aikaara-chat-input",m],["aikaara-typing-indicator",f],["aikaara-streaming-message",x],["aikaara-error-banner",k]];for(const[e,t]of i)customElements.get(e)||customElements.define(e,t)}y();exports.AikaaraChatBubble=h;exports.AikaaraChatHeader=b;exports.AikaaraChatInput=m;exports.AikaaraChatWidget=c;exports.AikaaraErrorBanner=k;exports.AikaaraMessageBubble=g;exports.AikaaraMessageList=u;exports.AikaaraStreamingMessage=x;exports.AikaaraTypingIndicator=f;exports.registerComponents=y;
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;