@aikaara/chat-sdk 0.1.3 → 0.1.4

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/headless.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./headless-DDmLD-ag.cjs");exports.ActionCableClient=e.ActionCableClient;exports.AikaaraChatClient=e.AikaaraChatClient;exports.ApiClient=e.ApiClient;exports.ChannelSubscription=e.ChannelSubscription;exports.ConnectionManager=e.ConnectionManager;exports.ConversationManager=e.ConversationManager;exports.EventEmitter=e.EventEmitter;exports.MessageStore=e.MessageStore;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./headless-CrgIWcf7.cjs");exports.ActionCableClient=e.ActionCableClient;exports.AikaaraChatClient=e.AikaaraChatClient;exports.ApiClient=e.ApiClient;exports.ChannelSubscription=e.ChannelSubscription;exports.ConnectionManager=e.ConnectionManager;exports.ConversationManager=e.ConversationManager;exports.EventEmitter=e.EventEmitter;exports.MessageStore=e.MessageStore;
@@ -120,6 +120,7 @@ export declare interface ChatEvents {
120
120
 
121
121
  export declare interface ConnectionConfig {
122
122
  baseUrl: string;
123
+ wsUrl?: string;
123
124
  userToken: string;
124
125
  reconnect?: boolean;
125
126
  maxReconnectAttempts?: number;
@@ -193,6 +194,8 @@ export declare class MessageStore {
193
194
  confirmOptimistic(tempId: string): void;
194
195
  addStreamingMessage(conversationId: string): Message;
195
196
  updateStreaming(content: string): void;
197
+ appendToStreaming(delta: string): void;
198
+ get streamingContent(): string;
196
199
  finalizeStreaming(usage?: {
197
200
  tokensInput: number;
198
201
  tokensOutput: number;
package/dist/headless.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as n, a as t, b as s, C as i, c as o, d as r, E as C, M as l } from "./headless-CXRux2Q-.mjs";
1
+ import { A as n, a as t, b as s, C as i, c as o, d as r, E as C, M as l } from "./headless-BhsiNVQj.mjs";
2
2
  export {
3
3
  n as ActionCableClient,
4
4
  t as AikaaraChatClient,
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./headless-DDmLD-ag.cjs"),a=require("./ui.cjs");function l(t){a.registerComponents();const r=document.createElement("aikaara-chat-widget"),n={baseUrl:"base-url",userToken:"user-token",apiKey:"api-key",title:"title",subtitle:"subtitle",theme:"theme",primaryColor:"primary-color",position:"position",width:"width",height:"height",placeholder:"placeholder",welcomeMessage:"welcome-message",avatarUrl:"avatar-url"};for(const[o,s]of Object.entries(n)){const i=t[o];i!=null&&r.setAttribute(s,String(i))}return r.configure(t),document.body.appendChild(r),r}function u(){const t=document.querySelector("aikaara-chat-widget");t&&t.remove()}exports.ActionCableClient=e.ActionCableClient;exports.AikaaraChatClient=e.AikaaraChatClient;exports.ApiClient=e.ApiClient;exports.ChannelSubscription=e.ChannelSubscription;exports.ConnectionManager=e.ConnectionManager;exports.ConversationManager=e.ConversationManager;exports.EventEmitter=e.EventEmitter;exports.MessageStore=e.MessageStore;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.AikaaraStreamingMessage=a.AikaaraStreamingMessage;exports.AikaaraTypingIndicator=a.AikaaraTypingIndicator;exports.registerComponents=a.registerComponents;exports.mount=l;exports.unmount=u;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./headless-CrgIWcf7.cjs"),a=require("./ui.cjs");function l(t){a.registerComponents();const r=document.createElement("aikaara-chat-widget"),n={baseUrl:"base-url",userToken:"user-token",apiKey:"api-key",title:"title",subtitle:"subtitle",theme:"theme",primaryColor:"primary-color",position:"position",width:"width",height:"height",placeholder:"placeholder",welcomeMessage:"welcome-message",avatarUrl:"avatar-url"};for(const[o,s]of Object.entries(n)){const i=t[o];i!=null&&r.setAttribute(s,String(i))}return r.configure(t),document.body.appendChild(r),r}function u(){const t=document.querySelector("aikaara-chat-widget");t&&t.remove()}exports.ActionCableClient=e.ActionCableClient;exports.AikaaraChatClient=e.AikaaraChatClient;exports.ApiClient=e.ApiClient;exports.ChannelSubscription=e.ChannelSubscription;exports.ConnectionManager=e.ConnectionManager;exports.ConversationManager=e.ConversationManager;exports.EventEmitter=e.EventEmitter;exports.MessageStore=e.MessageStore;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.AikaaraStreamingMessage=a.AikaaraStreamingMessage;exports.AikaaraTypingIndicator=a.AikaaraTypingIndicator;exports.registerComponents=a.registerComponents;exports.mount=l;exports.unmount=u;
package/dist/index.d.ts CHANGED
@@ -226,6 +226,7 @@ export declare interface ChatEvents {
226
226
 
227
227
  export declare interface ConnectionConfig {
228
228
  baseUrl: string;
229
+ wsUrl?: string;
229
230
  userToken: string;
230
231
  reconnect?: boolean;
231
232
  maxReconnectAttempts?: number;
@@ -299,6 +300,8 @@ export declare class MessageStore {
299
300
  confirmOptimistic(tempId: string): void;
300
301
  addStreamingMessage(conversationId: string): Message;
301
302
  updateStreaming(content: string): void;
303
+ appendToStreaming(delta: string): void;
304
+ get streamingContent(): string;
302
305
  finalizeStreaming(usage?: {
303
306
  tokensInput: number;
304
307
  tokensOutput: number;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as p, a as d, b as g, C as h, c as k, d as C, E as b, M as A } from "./headless-CXRux2Q-.mjs";
1
+ import { A as p, a as d, b as g, C as h, c as k, d as C, E as b, M as A } from "./headless-BhsiNVQj.mjs";
2
2
  import { registerComponents as n } from "./ui.mjs";
3
3
  import { AikaaraChatBubble as M, AikaaraChatHeader as w, AikaaraChatInput as y, AikaaraChatWidget as v, AikaaraErrorBanner as E, AikaaraMessageBubble as S, AikaaraMessageList as x, AikaaraStreamingMessage as B, AikaaraTypingIndicator as I } from "./ui.mjs";
4
4
  function l(a) {
package/dist/ui.cjs CHANGED
@@ -1,8 +1,8 @@
1
- "use strict";var T=Object.defineProperty;var C=(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)=>C(s,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./headless-DDmLD-ag.cjs");class L{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("header-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=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./headless-CrgIWcf7.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)}}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
2
  <style>
3
3
  :host {
4
4
  --aikaara-primary: ${e.primaryColor};
5
- --aikaara-primary-hover: ${this.darkenColor(e.primaryColor||o.DEFAULT_PRIMARY_COLOR)};
5
+ --aikaara-primary-hover: ${this.darkenColor(e.primaryColor||r.DEFAULT_PRIMARY_COLOR)};
6
6
  --aikaara-bg: #ffffff;
7
7
  --aikaara-bg-secondary: #f9fafb;
8
8
  --aikaara-text: #1f2937;
@@ -13,8 +13,8 @@
13
13
  --aikaara-panel-width: ${e.width}px;
14
14
  --aikaara-panel-height: ${e.height}px;
15
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;
16
+ --aikaara-offset-x: ${e.offset?.x??20}px;
17
+ --aikaara-offset-y: ${e.offset?.y??20}px;
18
18
  font-family: var(--aikaara-font);
19
19
  position: fixed;
20
20
  z-index: 9999;
@@ -52,6 +52,27 @@
52
52
  opacity: 1;
53
53
  transform: translateY(0) scale(1);
54
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
+ }
55
76
  </style>
56
77
 
57
78
  <aikaara-chat-bubble></aikaara-chat-bubble>
@@ -63,10 +84,10 @@
63
84
  ${e.avatarUrl?`avatar-url="${e.avatarUrl}"`:""}
64
85
  ></aikaara-chat-header>
65
86
  <aikaara-message-list></aikaara-message-list>
66
- <aikaara-chat-input placeholder="${e.placeholder||o.DEFAULT_PLACEHOLDER}"></aikaara-chat-input>
87
+ <aikaara-chat-input placeholder="${e.placeholder||r.DEFAULT_PLACEHOLDER}"></aikaara-chat-input>
67
88
  <aikaara-error-banner></aikaara-error-banner>
68
89
  </div>
69
- `}async initController(){var a;const e=this.getConfig();!e.baseUrl||!e.userToken||((a=this.controller)==null||a.disconnect(),this.controller=new L(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=`
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())}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=`
70
91
  <style>
71
92
  .bubble {
72
93
  width: var(--aikaara-bubble-size, 60px);
@@ -101,7 +122,7 @@
101
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"/>
102
123
  </svg>
103
124
  </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(){this.render(),this.bindClose()}attributeChangedCallback(){this.render(),this.bindClose()}bindClose(){var e;(e=this.shadow.querySelector(".close-btn"))==null||e.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("header-close",{bubbles:!0,composed:!0}))})}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=`
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=`
105
126
  <style>
106
127
  .header {
107
128
  display: flex;
@@ -180,14 +201,14 @@
180
201
  </style>
181
202
  <div class="header">
182
203
  <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>'}
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>'}
184
205
  </div>
185
206
  <div class="info">
186
207
  <div class="title">
187
208
  ${e}
188
- <span class="status-dot" style="background:${d}"></span>
209
+ <span class="status-dot" style="background:${o}"></span>
189
210
  </div>
190
- ${a?`<div class="subtitle">${a}</div>`:""}
211
+ ${t?`<div class="subtitle">${t}</div>`:""}
191
212
  </div>
192
213
  <button class="close-btn" aria-label="Close chat">
193
214
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
@@ -195,8 +216,13 @@
195
216
  </svg>
196
217
  </button>
197
218
  </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=`
219
+ `}setStatus(e){this.setAttribute("status",e)}}function l(i){let e=T(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 T(i){const e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return i.replace(/[&<>"']/g,t=>e[t])}const C=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(!C.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=`
199
220
  <style>
221
+ :host {
222
+ display: flex;
223
+ flex-direction: column;
224
+ min-height: 0;
225
+ }
200
226
  .message-list {
201
227
  flex: 1;
202
228
  overflow-y: auto;
@@ -298,7 +324,7 @@
298
324
  }
299
325
  </style>
300
326
  <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=`
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=`
302
328
  <style>
303
329
  :host { display: flex; flex-direction: column; }
304
330
  :host([role="user"]) { align-items: flex-end; }
@@ -328,9 +354,9 @@
328
354
  padding: 0 4px;
329
355
  }
330
356
  </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=`
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=`
334
360
  <style>
335
361
  .input-container {
336
362
  display: flex;
@@ -388,7 +414,7 @@
388
414
  </svg>
389
415
  </button>
390
416
  </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=`
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=`
392
418
  <style>
393
419
  :host { display: none; }
394
420
  :host([visible]) { display: block; }
@@ -422,7 +448,7 @@
422
448
  <span class="dot"></span>
423
449
  <span class="dot"></span>
424
450
  </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=`
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=`
426
452
  <style>
427
453
  :host {
428
454
  display: flex;
@@ -471,7 +497,7 @@
471
497
  }
472
498
  </style>
473
499
  <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=`
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=`
475
501
  <style>
476
502
  .banner {
477
503
  display: none;
@@ -499,4 +525,4 @@
499
525
  <span class="message"></span>
500
526
  <button class="dismiss">Dismiss</button>
501
527
  </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;
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;
package/dist/ui.d.ts CHANGED
@@ -119,6 +119,7 @@ declare interface ChatClientConfig extends ConnectionConfig {
119
119
 
120
120
  declare interface ConnectionConfig {
121
121
  baseUrl: string;
122
+ wsUrl?: string;
122
123
  userToken: string;
123
124
  reconnect?: boolean;
124
125
  maxReconnectAttempts?: number;