@aikaara/chat-sdk 0.1.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/ui.cjs ADDED
@@ -0,0 +1,502 @@
1
+ "use strict";var T=Object.defineProperty;var L=(s,t,e)=>t in s?T(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var i=(s,t,e)=>L(s,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./headless-CjIUiswe.cjs");class C{constructor(t,e){i(this,"client");i(this,"panel");i(this,"bubble");i(this,"header");i(this,"messageList");i(this,"input");i(this,"errorBanner");i(this,"isOpen",!1);this.client=new o.AikaaraChatClient(t),this.bubble=e.querySelector("aikaara-chat-bubble"),this.panel=e.querySelector(".aikaara-panel"),this.header=e.querySelector("aikaara-chat-header"),this.messageList=e.querySelector("aikaara-message-list"),this.input=e.querySelector("aikaara-chat-input"),this.errorBanner=e.querySelector("aikaara-error-banner"),t.welcomeMessage&&this.messageList.setWelcomeMessage(t.welcomeMessage),t.showTimestamps!==void 0&&this.messageList.setShowTimestamps(t.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("close",()=>{this.togglePanel(!1)}),this.input.addEventListener("send",(t=>{this.handleSend(t.detail.content)})),this.client.on("message:sent",t=>{this.messageList.addMessage(t)}),this.client.on("stream:start",()=>{this.messageList.removeTypingIndicator();const t=this.client.messages[this.client.messages.length-1];t&&this.messageList.addMessage(t)}),this.client.on("stream:update",({content:t})=>{this.messageList.updateStreamingContent(t)}),this.client.on("stream:end",()=>{this.messageList.finalizeStreaming()}),this.client.on("typing:start",()=>{const t=this.client.messages,e=t[t.length-1];(!e||e.status!=="streaming")&&this.messageList.showTypingIndicator()}),this.client.on("typing:stop",()=>{this.messageList.removeTypingIndicator()}),this.client.on("connection:state",t=>{this.header.setStatus(t),t==="connected"?(this.errorBanner.hide(),this.input.disabled=!1):t==="reconnecting"?(this.errorBanner.show("Connection lost. Reconnecting..."),this.input.disabled=!0):t==="disconnected"&&(this.input.disabled=!0)}),this.client.on("error",t=>{this.errorBanner.show(t.message,5e3)})}async handleSend(t){try{await this.client.sendMessage(t)}catch{this.errorBanner.show("Failed to send message",3e3)}}togglePanel(t){this.isOpen=t!==void 0?t:!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 b extends HTMLElement{constructor(){super();i(this,"shadow");i(this,"controller",null);i(this,"_config",{});this.shadow=this.attachShadow({mode:"open"})}static get observedAttributes(){return["base-url","user-token","api-key","title","subtitle","theme","primary-color","position","width","height","placeholder","welcome-message","avatar-url"]}connectedCallback(){this.render(),this.initController()}disconnectedCallback(){var e;(e=this.controller)==null||e.disconnect()}attributeChangedCallback(e,a,r){a!==r&&this.controller&&(this.render(),this.initController())}configure(e){this._config={...this._config,...e}}getConfig(){return{baseUrl:this.getAttribute("base-url")||this._config.baseUrl||"",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||o.DEFAULT_THEME,primaryColor:this.getAttribute("primary-color")||this._config.primaryColor||o.DEFAULT_PRIMARY_COLOR,position:this.getAttribute("position")||this._config.position||o.DEFAULT_POSITION,width:Number(this.getAttribute("width"))||this._config.width||o.DEFAULT_WIDGET_WIDTH,height:Number(this.getAttribute("height"))||this._config.height||o.DEFAULT_WIDGET_HEIGHT,fontFamily:this._config.fontFamily||o.DEFAULT_FONT_FAMILY,borderRadius:this._config.borderRadius??o.DEFAULT_BORDER_RADIUS,placeholder:this.getAttribute("placeholder")||this._config.placeholder||o.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||o.DEFAULT_OFFSET,conversationId:this._config.conversationId,systemPromptId:this._config.systemPromptId,channel:this._config.channel,onMessage:this._config.onMessage,onStatusChange:this._config.onStatusChange,onError:this._config.onError,onStreamUpdate:this._config.onStreamUpdate,onConnectionStateChange:this._config.onConnectionStateChange}}render(){var a,r;const e=this.getConfig();this.shadow.innerHTML=`
2
+ <style>
3
+ :host {
4
+ --aikaara-primary: ${e.primaryColor};
5
+ --aikaara-primary-hover: ${this.darkenColor(e.primaryColor||o.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: ${((a=e.offset)==null?void 0:a.x)??20}px;
17
+ --aikaara-offset-y: ${((r=e.offset)==null?void 0:r.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
+ </style>
56
+
57
+ <aikaara-chat-bubble></aikaara-chat-bubble>
58
+
59
+ <div class="aikaara-panel entering" hidden role="dialog" aria-label="Chat">
60
+ <aikaara-chat-header
61
+ title="${e.title||"Chat"}"
62
+ ${e.subtitle?`subtitle="${e.subtitle}"`:""}
63
+ ${e.avatarUrl?`avatar-url="${e.avatarUrl}"`:""}
64
+ ></aikaara-chat-header>
65
+ <aikaara-message-list></aikaara-message-list>
66
+ <aikaara-chat-input placeholder="${e.placeholder||o.DEFAULT_PLACEHOLDER}"></aikaara-chat-input>
67
+ <aikaara-error-banner></aikaara-error-banner>
68
+ </div>
69
+ `}async initController(){var a;const e=this.getConfig();!e.baseUrl||!e.userToken||((a=this.controller)==null||a.disconnect(),this.controller=new C(e,this.shadow),await this.controller.connect())}darkenColor(e){try{const a=parseInt(e.replace("#",""),16),r=Math.max(0,(a>>16)-20),n=Math.max(0,(a>>8&255)-20),d=Math.max(0,(a&255)-20);return`#${(r<<16|n<<8|d).toString(16).padStart(6,"0")}`}catch{return e}}}class p extends HTMLElement{constructor(){super();i(this,"shadow");this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){var e;this.render(),(e=this.shadow.querySelector(".bubble"))==null||e.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("toggle",{bubbles:!0,composed:!0}))})}render(){this.shadow.innerHTML=`
70
+ <style>
71
+ .bubble {
72
+ width: var(--aikaara-bubble-size, 60px);
73
+ height: var(--aikaara-bubble-size, 60px);
74
+ border-radius: 50%;
75
+ background: var(--aikaara-primary, #6366f1);
76
+ color: #ffffff;
77
+ border: none;
78
+ cursor: pointer;
79
+ display: flex;
80
+ align-items: center;
81
+ justify-content: center;
82
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
83
+ transition: transform 200ms ease, box-shadow 200ms ease;
84
+ }
85
+ .bubble:hover {
86
+ transform: scale(1.05);
87
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
88
+ }
89
+ .bubble svg {
90
+ width: 28px;
91
+ height: 28px;
92
+ }
93
+ .bubble-text {
94
+ font-family: var(--aikaara-font, system-ui, sans-serif);
95
+ font-size: 12px;
96
+ font-weight: 500;
97
+ }
98
+ </style>
99
+ <button class="bubble" aria-label="Open chat">
100
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
101
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
102
+ </svg>
103
+ </button>
104
+ `}setIcon(e){const a=this.shadow.querySelector(".bubble");a&&(a.innerHTML=e)}}class u extends HTMLElement{constructor(){super();i(this,"shadow");this.shadow=this.attachShadow({mode:"open"})}static get observedAttributes(){return["title","subtitle","avatar-url","status"]}connectedCallback(){var e;this.render(),(e=this.shadow.querySelector(".close-btn"))==null||e.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("close",{bubbles:!0,composed:!0}))})}attributeChangedCallback(){this.render()}render(){const e=this.getAttribute("title")||"Chat",a=this.getAttribute("subtitle")||"",r=this.getAttribute("avatar-url"),n=this.getAttribute("status")||"connected",d=n==="connected"?"#10b981":n==="connecting"||n==="reconnecting"?"#f59e0b":"#ef4444";this.shadow.innerHTML=`
105
+ <style>
106
+ .header {
107
+ display: flex;
108
+ align-items: center;
109
+ gap: 12px;
110
+ padding: 14px 16px;
111
+ background: var(--aikaara-primary, #6366f1);
112
+ color: #ffffff;
113
+ flex-shrink: 0;
114
+ }
115
+ .avatar {
116
+ width: 36px;
117
+ height: 36px;
118
+ border-radius: 50%;
119
+ background: rgba(255,255,255,0.2);
120
+ display: flex;
121
+ align-items: center;
122
+ justify-content: center;
123
+ flex-shrink: 0;
124
+ overflow: hidden;
125
+ }
126
+ .avatar img {
127
+ width: 100%;
128
+ height: 100%;
129
+ object-fit: cover;
130
+ }
131
+ .avatar svg {
132
+ width: 20px;
133
+ height: 20px;
134
+ }
135
+ .info {
136
+ flex: 1;
137
+ min-width: 0;
138
+ }
139
+ .title {
140
+ font-size: 15px;
141
+ font-weight: 600;
142
+ line-height: 1.2;
143
+ display: flex;
144
+ align-items: center;
145
+ gap: 6px;
146
+ }
147
+ .status-dot {
148
+ width: 8px;
149
+ height: 8px;
150
+ border-radius: 50%;
151
+ flex-shrink: 0;
152
+ }
153
+ .subtitle {
154
+ font-size: 12px;
155
+ opacity: 0.85;
156
+ white-space: nowrap;
157
+ overflow: hidden;
158
+ text-overflow: ellipsis;
159
+ }
160
+ .close-btn {
161
+ background: none;
162
+ border: none;
163
+ color: #ffffff;
164
+ cursor: pointer;
165
+ padding: 4px;
166
+ border-radius: 4px;
167
+ display: flex;
168
+ align-items: center;
169
+ justify-content: center;
170
+ opacity: 0.8;
171
+ transition: opacity 200ms;
172
+ }
173
+ .close-btn:hover {
174
+ opacity: 1;
175
+ }
176
+ .close-btn svg {
177
+ width: 20px;
178
+ height: 20px;
179
+ }
180
+ </style>
181
+ <div class="header">
182
+ <div class="avatar">
183
+ ${r?`<img src="${r}" 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>'}
184
+ </div>
185
+ <div class="info">
186
+ <div class="title">
187
+ ${e}
188
+ <span class="status-dot" style="background:${d}"></span>
189
+ </div>
190
+ ${a?`<div class="subtitle">${a}</div>`:""}
191
+ </div>
192
+ <button class="close-btn" aria-label="Close chat">
193
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
194
+ <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
195
+ </svg>
196
+ </button>
197
+ </div>
198
+ `}setStatus(e){this.setAttribute("status",e)}}function c(s){let t=A(s);return t=t.replace(/```(\w*)\n([\s\S]*?)```/g,(e,a,r)=>`<pre><code>${r.trim()}</code></pre>`),t=t.replace(/`([^`]+)`/g,"<code>$1</code>"),t=t.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),t=t.replace(/\*(.+?)\*/g,"<em>$1</em>"),t=t.replace(/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g,'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'),t=t.replace(/\n/g,"<br>"),t}function A(s){const t={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return s.replace(/[&<>"']/g,e=>t[e])}const E=new Set(["p","br","strong","em","code","pre","a","ul","ol","li","blockquote","h1","h2","h3","h4","h5","h6","span","div"]),S={a:new Set(["href","target","rel"]),code:new Set(["class"]),pre:new Set(["class"]),span:new Set(["class"]),div:new Set(["class"])};function h(s){const t=document.createElement("template");return t.innerHTML=s,g(t.content),t.innerHTML}function g(s){const t=Array.from(s.childNodes);for(const e of t)if(e.nodeType===Node.ELEMENT_NODE){const a=e,r=a.tagName.toLowerCase();if(!E.has(r)){const l=document.createTextNode(a.textContent||"");s.replaceChild(l,e);continue}const n=S[r]||new Set,d=Array.from(a.attributes);for(const l of d)n.has(l.name)||a.removeAttribute(l.name);if(a.hasAttribute("href")){const l=a.getAttribute("href")||"";!l.startsWith("http://")&&!l.startsWith("https://")&&!l.startsWith("/")&&a.removeAttribute("href")}g(e)}}class m extends HTMLElement{constructor(){super();i(this,"shadow");i(this,"container");i(this,"welcomeMessage","");i(this,"showTimestamps",!0);this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.shadow.innerHTML=`
199
+ <style>
200
+ .message-list {
201
+ flex: 1;
202
+ overflow-y: auto;
203
+ padding: 16px;
204
+ display: flex;
205
+ flex-direction: column;
206
+ gap: 8px;
207
+ scroll-behavior: smooth;
208
+ }
209
+ .message-list::-webkit-scrollbar { width: 6px; }
210
+ .message-list::-webkit-scrollbar-track { background: transparent; }
211
+ .message-list::-webkit-scrollbar-thumb { background: var(--aikaara-border, #e5e7eb); border-radius: 3px; }
212
+ .message-wrap { display: flex; flex-direction: column; }
213
+ .message-wrap.user { align-items: flex-end; }
214
+ .message-wrap.assistant { align-items: flex-start; }
215
+ .bubble {
216
+ max-width: 85%;
217
+ padding: 10px 14px;
218
+ border-radius: var(--aikaara-radius, 12px);
219
+ font-size: 14px;
220
+ line-height: 1.5;
221
+ word-wrap: break-word;
222
+ overflow-wrap: break-word;
223
+ }
224
+ .bubble.user {
225
+ background: var(--aikaara-primary, #6366f1);
226
+ color: #ffffff;
227
+ border-bottom-right-radius: 4px;
228
+ }
229
+ .bubble.assistant {
230
+ background: var(--aikaara-bg-secondary, #f9fafb);
231
+ color: var(--aikaara-text, #1f2937);
232
+ border-bottom-left-radius: 4px;
233
+ }
234
+ .bubble pre {
235
+ background: rgba(0,0,0,0.06);
236
+ padding: 8px 12px;
237
+ border-radius: 6px;
238
+ overflow-x: auto;
239
+ font-size: 13px;
240
+ margin: 8px 0;
241
+ }
242
+ .bubble code {
243
+ font-family: 'SF Mono', 'Fira Code', monospace;
244
+ font-size: 13px;
245
+ }
246
+ .bubble.assistant code:not(pre code) {
247
+ background: rgba(0,0,0,0.06);
248
+ padding: 2px 4px;
249
+ border-radius: 3px;
250
+ }
251
+ .bubble a { color: inherit; text-decoration: underline; }
252
+ .timestamp {
253
+ font-size: 11px;
254
+ color: var(--aikaara-text-secondary, #6b7280);
255
+ margin-top: 2px;
256
+ padding: 0 4px;
257
+ }
258
+ .welcome {
259
+ text-align: center;
260
+ color: var(--aikaara-text-secondary, #6b7280);
261
+ font-size: 14px;
262
+ padding: 24px 16px;
263
+ }
264
+ .streaming-cursor::after {
265
+ content: '\\25CF';
266
+ animation: blink 1s infinite;
267
+ margin-left: 2px;
268
+ font-size: 10px;
269
+ vertical-align: middle;
270
+ }
271
+ @keyframes blink {
272
+ 0%, 100% { opacity: 1; }
273
+ 50% { opacity: 0; }
274
+ }
275
+ .typing-indicator {
276
+ display: flex;
277
+ align-items: center;
278
+ gap: 4px;
279
+ padding: 10px 14px;
280
+ align-self: flex-start;
281
+ background: var(--aikaara-bg-secondary, #f9fafb);
282
+ border-radius: var(--aikaara-radius, 12px);
283
+ border-bottom-left-radius: 4px;
284
+ }
285
+ .typing-indicator .dot {
286
+ width: 6px;
287
+ height: 6px;
288
+ border-radius: 50%;
289
+ background: var(--aikaara-text-secondary, #6b7280);
290
+ animation: typing-bounce 1.4s infinite ease-in-out;
291
+ }
292
+ .typing-indicator .dot:nth-child(1) { animation-delay: 0ms; }
293
+ .typing-indicator .dot:nth-child(2) { animation-delay: 200ms; }
294
+ .typing-indicator .dot:nth-child(3) { animation-delay: 400ms; }
295
+ @keyframes typing-bounce {
296
+ 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
297
+ 30% { transform: translateY(-4px); opacity: 1; }
298
+ }
299
+ </style>
300
+ <div class="message-list"></div>
301
+ `,this.container=this.shadow.querySelector(".message-list")}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">${h(c(this.welcomeMessage))}</div>`;return}for(const a of e)this.appendMessageElement(a);this.scrollToBottom()}}addMessage(e){const a=this.container.querySelector(".welcome");a&&a.remove(),this.appendMessageElement(e),this.scrollToBottom()}updateStreamingContent(e){const a=this.container.querySelector('[data-streaming="true"] .bubble');a&&(a.innerHTML=h(c(e)),a.classList.add("streaming-cursor"),this.scrollToBottom())}finalizeStreaming(){const e=this.container.querySelector('[data-streaming="true"]');if(e){e.removeAttribute("data-streaming");const a=e.querySelector(".bubble");a==null||a.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(){var e;(e=this.container.querySelector('[data-typing="true"]'))==null||e.remove()}appendMessageElement(e){const a=document.createElement("div");a.classList.add("message-wrap",e.role),e.status==="streaming"&&a.setAttribute("data-streaming","true");const r=document.createElement("div");if(r.classList.add("bubble",e.role),e.role==="user"?r.textContent=e.content:(r.innerHTML=h(c(e.content||"")),e.status==="streaming"&&r.classList.add("streaming-cursor")),a.appendChild(r),this.showTimestamps&&e.createdAt){const n=document.createElement("div");n.classList.add("timestamp"),n.textContent=this.formatTime(e.createdAt),a.appendChild(n)}this.container.appendChild(a)}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 f extends HTMLElement{constructor(){super();i(this,"shadow");this.shadow=this.attachShadow({mode:"open"})}static get observedAttributes(){return["role","content","timestamp"]}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}render(){const e=this.getAttribute("role")||"user",a=this.getAttribute("content")||"",r=this.getAttribute("timestamp")||"",n=e==="user"?document.createTextNode(a).textContent||"":h(c(a));this.shadow.innerHTML=`
302
+ <style>
303
+ :host { display: flex; flex-direction: column; }
304
+ :host([role="user"]) { align-items: flex-end; }
305
+ :host([role="assistant"]) { align-items: flex-start; }
306
+ .bubble {
307
+ max-width: 85%;
308
+ padding: 10px 14px;
309
+ border-radius: var(--aikaara-radius, 12px);
310
+ font-size: 14px;
311
+ line-height: 1.5;
312
+ word-wrap: break-word;
313
+ }
314
+ .bubble.user {
315
+ background: var(--aikaara-primary, #6366f1);
316
+ color: #fff;
317
+ border-bottom-right-radius: 4px;
318
+ }
319
+ .bubble.assistant {
320
+ background: var(--aikaara-bg-secondary, #f9fafb);
321
+ color: var(--aikaara-text, #1f2937);
322
+ border-bottom-left-radius: 4px;
323
+ }
324
+ .timestamp {
325
+ font-size: 11px;
326
+ color: var(--aikaara-text-secondary, #6b7280);
327
+ margin-top: 2px;
328
+ padding: 0 4px;
329
+ }
330
+ </style>
331
+ <div class="bubble ${e}">${n}</div>
332
+ ${r?`<div class="timestamp">${r}</div>`:""}
333
+ `}}class x extends HTMLElement{constructor(){super();i(this,"shadow");i(this,"textarea");i(this,"sendBtn");i(this,"_disabled",!1);this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){const e=this.getAttribute("placeholder")||"Type a message...";this.shadow.innerHTML=`
334
+ <style>
335
+ .input-container {
336
+ display: flex;
337
+ align-items: flex-end;
338
+ gap: 8px;
339
+ padding: 12px 16px;
340
+ border-top: 1px solid var(--aikaara-border, #e5e7eb);
341
+ background: var(--aikaara-bg, #ffffff);
342
+ }
343
+ textarea {
344
+ flex: 1;
345
+ resize: none;
346
+ border: 1px solid var(--aikaara-border, #e5e7eb);
347
+ border-radius: 8px;
348
+ padding: 10px 12px;
349
+ font-family: var(--aikaara-font, system-ui, sans-serif);
350
+ font-size: 14px;
351
+ color: var(--aikaara-text, #1f2937);
352
+ background: var(--aikaara-bg, #ffffff);
353
+ outline: none;
354
+ min-height: 40px;
355
+ max-height: 120px;
356
+ line-height: 1.4;
357
+ transition: border-color 200ms ease;
358
+ }
359
+ textarea:focus {
360
+ border-color: var(--aikaara-primary, #6366f1);
361
+ }
362
+ textarea::placeholder {
363
+ color: var(--aikaara-text-secondary, #6b7280);
364
+ }
365
+ .send-btn {
366
+ width: 40px;
367
+ height: 40px;
368
+ border: none;
369
+ border-radius: 50%;
370
+ background: var(--aikaara-primary, #6366f1);
371
+ color: #ffffff;
372
+ cursor: pointer;
373
+ display: flex;
374
+ align-items: center;
375
+ justify-content: center;
376
+ flex-shrink: 0;
377
+ transition: background 200ms, opacity 200ms;
378
+ }
379
+ .send-btn:hover { background: var(--aikaara-primary-hover, #4f46e5); }
380
+ .send-btn:disabled { opacity: 0.5; cursor: not-allowed; }
381
+ .send-btn svg { width: 18px; height: 18px; }
382
+ </style>
383
+ <div class="input-container">
384
+ <textarea rows="1" placeholder="${e}"></textarea>
385
+ <button class="send-btn" aria-label="Send message" disabled>
386
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
387
+ <line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/>
388
+ </svg>
389
+ </button>
390
+ </div>
391
+ `,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",a=>{a.key==="Enter"&&!a.shiftKey&&(a.preventDefault(),this.handleSend())}),this.sendBtn.addEventListener("click",()=>this.handleSend())}set disabled(e){var a;this._disabled=e,this.textarea&&(this.textarea.disabled=e),this.sendBtn&&(this.sendBtn.disabled=e||!((a=this.textarea)!=null&&a.value.trim()))}get disabled(){return this._disabled}focus(){var e;(e=this.textarea)==null||e.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 k extends HTMLElement{constructor(){super();i(this,"shadow");this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.shadow.innerHTML=`
392
+ <style>
393
+ :host { display: none; }
394
+ :host([visible]) { display: block; }
395
+ .typing {
396
+ display: flex;
397
+ align-items: center;
398
+ gap: 4px;
399
+ padding: 10px 14px;
400
+ background: var(--aikaara-bg-secondary, #f9fafb);
401
+ border-radius: var(--aikaara-radius, 12px);
402
+ border-bottom-left-radius: 4px;
403
+ width: fit-content;
404
+ }
405
+ .dot {
406
+ width: 6px;
407
+ height: 6px;
408
+ border-radius: 50%;
409
+ background: var(--aikaara-text-secondary, #6b7280);
410
+ animation: bounce 1.4s infinite ease-in-out;
411
+ }
412
+ .dot:nth-child(1) { animation-delay: 0ms; }
413
+ .dot:nth-child(2) { animation-delay: 200ms; }
414
+ .dot:nth-child(3) { animation-delay: 400ms; }
415
+ @keyframes bounce {
416
+ 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
417
+ 30% { transform: translateY(-4px); opacity: 1; }
418
+ }
419
+ </style>
420
+ <div class="typing">
421
+ <span class="dot"></span>
422
+ <span class="dot"></span>
423
+ <span class="dot"></span>
424
+ </div>
425
+ `}show(){this.setAttribute("visible","")}hide(){this.removeAttribute("visible")}}class y extends HTMLElement{constructor(){super();i(this,"shadow");i(this,"bubble");this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.shadow.innerHTML=`
426
+ <style>
427
+ :host {
428
+ display: flex;
429
+ flex-direction: column;
430
+ align-items: flex-start;
431
+ }
432
+ .bubble {
433
+ max-width: 85%;
434
+ padding: 10px 14px;
435
+ border-radius: var(--aikaara-radius, 12px);
436
+ border-bottom-left-radius: 4px;
437
+ background: var(--aikaara-bg-secondary, #f9fafb);
438
+ color: var(--aikaara-text, #1f2937);
439
+ font-size: 14px;
440
+ line-height: 1.5;
441
+ word-wrap: break-word;
442
+ min-height: 20px;
443
+ }
444
+ .bubble pre {
445
+ background: rgba(0,0,0,0.06);
446
+ padding: 8px 12px;
447
+ border-radius: 6px;
448
+ overflow-x: auto;
449
+ font-size: 13px;
450
+ margin: 8px 0;
451
+ }
452
+ .bubble code {
453
+ font-family: 'SF Mono', 'Fira Code', monospace;
454
+ font-size: 13px;
455
+ }
456
+ .bubble code:not(pre code) {
457
+ background: rgba(0,0,0,0.06);
458
+ padding: 2px 4px;
459
+ border-radius: 3px;
460
+ }
461
+ .cursor::after {
462
+ content: '\\25CF';
463
+ animation: blink 1s infinite;
464
+ margin-left: 2px;
465
+ font-size: 10px;
466
+ vertical-align: middle;
467
+ }
468
+ @keyframes blink {
469
+ 0%, 100% { opacity: 1; }
470
+ 50% { opacity: 0; }
471
+ }
472
+ </style>
473
+ <div class="bubble cursor"></div>
474
+ `,this.bubble=this.shadow.querySelector(".bubble")}updateContent(e){this.bubble&&(this.bubble.innerHTML=h(c(e)),this.bubble.classList.add("cursor"))}finalize(){var e;(e=this.bubble)==null||e.classList.remove("cursor")}}class v extends HTMLElement{constructor(){super();i(this,"shadow");i(this,"container");i(this,"dismissTimer",null);this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){var e;this.shadow.innerHTML=`
475
+ <style>
476
+ .banner {
477
+ display: none;
478
+ padding: 8px 16px;
479
+ background: #fef2f2;
480
+ color: #dc2626;
481
+ font-size: 13px;
482
+ text-align: center;
483
+ border-top: 1px solid #fecaca;
484
+ }
485
+ .banner.visible {
486
+ display: block;
487
+ }
488
+ .dismiss {
489
+ background: none;
490
+ border: none;
491
+ color: #dc2626;
492
+ cursor: pointer;
493
+ font-size: 12px;
494
+ text-decoration: underline;
495
+ margin-left: 8px;
496
+ }
497
+ </style>
498
+ <div class="banner">
499
+ <span class="message"></span>
500
+ <button class="dismiss">Dismiss</button>
501
+ </div>
502
+ `,this.container=this.shadow.querySelector(".banner"),(e=this.shadow.querySelector(".dismiss"))==null||e.addEventListener("click",()=>this.hide())}show(e,a){const r=this.container.querySelector(".message");r&&(r.textContent=e),this.container.classList.add("visible"),this.dismissTimer&&clearTimeout(this.dismissTimer),a&&(this.dismissTimer=setTimeout(()=>this.hide(),a))}hide(){this.container.classList.remove("visible"),this.dismissTimer&&(clearTimeout(this.dismissTimer),this.dismissTimer=null)}}function w(){const s=[["aikaara-chat-widget",b],["aikaara-chat-bubble",p],["aikaara-chat-header",u],["aikaara-message-list",m],["aikaara-message-bubble",f],["aikaara-chat-input",x],["aikaara-typing-indicator",k],["aikaara-streaming-message",y],["aikaara-error-banner",v]];for(const[t,e]of s)customElements.get(t)||customElements.define(t,e)}w();exports.AikaaraChatBubble=p;exports.AikaaraChatHeader=u;exports.AikaaraChatInput=x;exports.AikaaraChatWidget=b;exports.AikaaraErrorBanner=v;exports.AikaaraMessageBubble=f;exports.AikaaraMessageList=m;exports.AikaaraStreamingMessage=y;exports.AikaaraTypingIndicator=k;exports.registerComponents=w;