@aikaara/chat-sdk 0.1.2 → 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/cdn/aikaara-chat.iife.js +45 -19
- package/dist/{headless-CXRux2Q-.mjs → headless-BhsiNVQj.mjs} +185 -199
- package/dist/headless-CrgIWcf7.cjs +1 -0
- package/dist/headless.cjs +1 -1
- package/dist/headless.d.ts +3 -0
- package/dist/headless.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.mjs +1 -1
- package/dist/ui.cjs +45 -19
- package/dist/ui.d.ts +2 -0
- package/dist/ui.mjs +216 -210
- package/package.json +2 -2
- package/dist/headless-DDmLD-ag.cjs +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aikaara/chat-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Aikaara Chat SDK — embeddable chat widget and headless client",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"typescript": "^5.7.0",
|
|
39
|
-
"vite": "^
|
|
39
|
+
"vite": "^7.3.1",
|
|
40
40
|
"vite-plugin-dts": "^4.0.0"
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var E=Object.defineProperty;var T=(a,t,e)=>t in a?E(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e;var o=(a,t,e)=>T(a,typeof t!="symbol"?t+"":t,e);class b{constructor(t,e){o(this,"identifier");o(this,"callbacks",{});o(this,"sendFn");this.identifier=t,this.sendFn=e}onReceived(t){return this.callbacks.received=t,this}onConnected(t){return this.callbacks.connected=t,this}onDisconnected(t){return this.callbacks.disconnected=t,this}onRejected(t){return this.callbacks.rejected=t,this}perform(t,e={}){this.sendFn({action:t,...e})}_notifyReceived(t){var e,s;(s=(e=this.callbacks).received)==null||s.call(e,t)}_notifyConnected(){var t,e;(e=(t=this.callbacks).connected)==null||e.call(t)}_notifyDisconnected(){var t,e;(e=(t=this.callbacks).disconnected)==null||e.call(t)}_notifyRejected(){var t,e;(e=(t=this.callbacks).rejected)==null||e.call(t)}}class f{constructor(t){o(this,"ws",null);o(this,"url");o(this,"subscriptions",new Map);o(this,"welcomePromise",null);o(this,"pendingSubscriptions",new Map);this.url=t}connect(){return new Promise((t,e)=>{this.welcomePromise={resolve:t,reject:e},this.ws=new WebSocket(this.url),this.ws.onopen=()=>{},this.ws.onmessage=s=>{this.handleMessage(s)},this.ws.onerror=()=>{var n;const s=new Error("WebSocket connection error");(n=this.welcomePromise)==null||n.reject(s),this.welcomePromise=null},this.ws.onclose=()=>{this.subscriptions.forEach(s=>s._notifyDisconnected())}})}disconnect(){this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.subscriptions.forEach(t=>t._notifyDisconnected()),this.subscriptions.clear()}subscribe(t){const e=JSON.stringify(t),s=new b(e,n=>{this.send({command:"message",identifier:e,data:JSON.stringify(n)})});return this.subscriptions.set(e,s),this.send({command:"subscribe",identifier:e}),s}subscribeAsync(t){const e=this.subscribe(t),s=e.identifier;return new Promise((n,i)=>{this.pendingSubscriptions.set(s,{resolve:()=>n(e),reject:i}),setTimeout(()=>{this.pendingSubscriptions.has(s)&&(this.pendingSubscriptions.delete(s),i(new Error(`Subscription timeout for ${s}`)))},1e4)})}unsubscribe(t){this.send({command:"unsubscribe",identifier:t}),this.subscriptions.delete(t)}perform(t,e,s={}){this.send({command:"message",identifier:t,data:JSON.stringify({action:e,...s})})}get isConnected(){var t;return((t=this.ws)==null?void 0:t.readyState)===WebSocket.OPEN}send(t){var e;((e=this.ws)==null?void 0:e.readyState)===WebSocket.OPEN&&this.ws.send(JSON.stringify(t))}handleMessage(t){var s;let e;try{e=JSON.parse(t.data)}catch{return}switch(e.type){case"welcome":(s=this.welcomePromise)==null||s.resolve(),this.welcomePromise=null;break;case"ping":break;case"confirm_subscription":{const n=e.identifier,i=this.subscriptions.get(n);i==null||i._notifyConnected();const c=this.pendingSubscriptions.get(n);c&&(c.resolve(),this.pendingSubscriptions.delete(n));break}case"reject_subscription":{const n=e.identifier,i=this.subscriptions.get(n);i==null||i._notifyRejected(),this.subscriptions.delete(n);const c=this.pendingSubscriptions.get(n);c&&(c.reject(new Error(`Subscription rejected: ${n}`)),this.pendingSubscriptions.delete(n));break}case"disconnect":this.subscriptions.forEach(n=>n._notifyDisconnected());break;default:{if(e.identifier&&e.message!==void 0){const n=this.subscriptions.get(e.identifier);n==null||n._notifyReceived(e.message)}break}}}}class _{constructor(){o(this,"handlers",new Map)}on(t,e){return this.handlers.has(t)||this.handlers.set(t,new Set),this.handlers.get(t).add(e),()=>this.off(t,e)}off(t,e){var s;(s=this.handlers.get(t))==null||s.delete(e)}emit(t,e){var s;(s=this.handlers.get(t))==null||s.forEach(n=>{try{n(e)}catch(i){console.error(`Error in event handler for "${t}":`,i)}})}removeAllListeners(){this.handlers.clear()}}const I=1e3,A=10,k=400,C=600,M="#6366f1",O=12,U="system-ui, -apple-system, sans-serif",D="Type a message...",F="bottom-right",L="light",R={x:20,y:20},p="aikaara_conversation_id";class S extends _{constructor(e){super();o(this,"client");o(this,"config");o(this,"state","disconnected");o(this,"reconnectAttempt",0);o(this,"reconnectTimer",null);this.config=e;const s=this.buildWsUrl(e.baseUrl,e.userToken);this.client=new f(s)}async connect(){this.setState("connecting");try{await this.client.connect(),this.setState("connected"),this.reconnectAttempt=0}catch(e){if(this.setState("disconnected"),this.config.reconnect!==!1)this.scheduleReconnect();else throw e}}async disconnect(){this.clearReconnectTimer(),this.client.disconnect(),this.setState("disconnected")}subscribeToConversation(e){return this.client.subscribeAsync({channel:"ConversationChannel",conversation_id:e})}sendMessage(e,s){const n=JSON.stringify({channel:"ConversationChannel",conversation_id:e});this.client.perform(n,"send_message",{content:s})}sendUserEvent(e,s,n,i){const c=JSON.stringify({channel:"ConversationChannel",conversation_id:e});this.client.perform(c,"send_user_event",{event_key:s,...n&&{value:n},...i&&{source:i}})}get connectionState(){return this.state}setState(e){this.state!==e&&(this.state=e,this.emit("connection:state",e))}scheduleReconnect(){const e=this.config.maxReconnectAttempts??A;if(this.reconnectAttempt>=e){this.emit("error",new Error("Max reconnection attempts reached"));return}this.setState("reconnecting");const n=(this.config.reconnectInterval??I)*Math.pow(2,this.reconnectAttempt);this.reconnectAttempt++,this.reconnectTimer=setTimeout(async()=>{try{const i=this.buildWsUrl(this.config.baseUrl,this.config.userToken);this.client=new f(i),await this.connect()}catch{}},n)}clearReconnectTimer(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}buildWsUrl(e,s){return`${e.replace(/^http/,"ws")}/cable?token=${s}`}}class v{constructor(t,e,s){o(this,"baseUrl");o(this,"apiKey");o(this,"userToken");this.baseUrl=t,this.userToken=e,this.apiKey=s}async createConversation(t){const e={conversation:{...t.extUid&&{ext_uid:t.extUid},...t.systemPromptId&&{system_prompt_id:t.systemPromptId},...t.channel&&{channel:t.channel},...t.title&&{title:t.title}}};return this.request("POST","/api/v1/conversations",e)}async getMessages(t){return(await this.request("GET",`/api/v1/conversations/${t}/messages`)).map(this.mapMessage)}mapMessage(t){var e;return{id:String(t.id),conversationId:String(t.conversation_id),role:t.role,content:t.content||"",toolCalls:(e=t.tool_calls)==null?void 0:e.map(s=>({id:s.id,type:s.type,function:s.function})),toolCallResults:t.tool_call_results,tokensInput:t.tokens_input,tokensOutput:t.tokens_output,metadata:t.metadata,createdAt:t.created_at,status:"complete"}}async request(t,e,s){const n={"Content-Type":"application/json",Accept:"application/json"};this.apiKey&&(n["X-Api-Key"]=this.apiKey);const i=`${this.baseUrl}${e}`,c={method:t,headers:n};s&&(c.body=JSON.stringify(s));const l=await fetch(i,c);if(!l.ok){const u=await l.text();let g;try{const m=JSON.parse(u);g=m.error||m.message||u}catch{g=u}throw new Error(`API error ${l.status}: ${g}`)}const h=await l.json();if(h&&typeof h=="object"&&"success"in h){if(!h.success)throw new Error(`API error: ${h.message||"Request failed"}`);return h.data}return h}}class y{constructor(){o(this,"_messages",[]);o(this,"optimisticCounter",0)}get messages(){return[...this._messages]}addOptimistic(t,e,s){const n={id:`optimistic_${++this.optimisticCounter}`,conversationId:s,role:t,content:e,createdAt:new Date().toISOString(),status:"sending"};return this._messages.push(n),n}confirmOptimistic(t){const e=this._messages.find(s=>s.id===t);e&&(e.status="sent")}addStreamingMessage(t){const e={id:`streaming_${Date.now()}`,conversationId:t,role:"assistant",content:"",createdAt:new Date().toISOString(),status:"streaming"};return this._messages.push(e),e}updateStreaming(t){const e=this._messages.findLast(s=>s.status==="streaming");e&&(e.content=t)}finalizeStreaming(t){const e=this._messages.findLast(s=>s.status==="streaming");return e&&(e.status="complete",t&&(e.tokensInput=t.tokensInput,e.tokensOutput=t.tokensOutput)),e}addMessage(t){this._messages.push(t)}setMessages(t){this._messages=[...t]}clear(){this._messages=[]}}class w{constructor(t,e=!0){o(this,"_conversationId");o(this,"persist");this.persist=e,this._conversationId=t||this.loadFromStorage()}get conversationId(){return this._conversationId}set conversationId(t){this._conversationId=t,this.persist&&t&&this.saveToStorage(t)}clear(){if(this._conversationId=null,this.persist)try{localStorage.removeItem(p)}catch{}}loadFromStorage(){if(!this.persist)return null;try{return localStorage.getItem(p)}catch{return null}}saveToStorage(t){try{localStorage.setItem(p,t)}catch{}}}class N extends _{constructor(e){super();o(this,"connection");o(this,"api");o(this,"messageStore");o(this,"conversationManager");o(this,"subscription",null);o(this,"config");this.config=e,this.connection=new S(e),this.api=new v(e.baseUrl,e.userToken,e.apiKey),this.messageStore=new y,this.conversationManager=new w(e.conversationId),this.connection.on("connection:state",s=>{var n,i;this.emit("connection:state",s),(i=(n=this.config).onConnectionStateChange)==null||i.call(n,s)}),this.connection.on("error",s=>{var n,i;this.emit("error",s),(i=(n=this.config).onError)==null||i.call(n,s)})}async connect(){if(await this.connection.connect(),!this.conversationManager.conversationId){const e=await this.api.createConversation({systemPromptId:this.config.systemPromptId,channel:this.config.channel||"widget",extUid:this.config.extUid});this.conversationManager.conversationId=String(e.id)}this.subscription=await this.connection.subscribeToConversation(this.conversationManager.conversationId),this.subscription.onReceived(e=>{this.handleBroadcast(e)}),await this.loadHistory()}async sendMessage(e){var i,c;const s=this.conversationManager.conversationId;if(!s)throw new Error("No active conversation");const n=this.messageStore.addOptimistic("user",e,s);this.emit("message:sent",n),(c=(i=this.config).onMessage)==null||c.call(i,n),this.connection.sendMessage(s,e)}async sendUserEvent(e,s,n){const i=this.conversationManager.conversationId;if(!i)throw new Error("No active conversation");this.connection.sendUserEvent(i,e,s,n)}async loadHistory(){const e=this.conversationManager.conversationId;if(!e)return[];try{const s=await this.api.getMessages(e);return this.messageStore.setMessages(s),s}catch{return[]}}get messages(){return this.messageStore.messages}get conversationId(){return this.conversationManager.conversationId}get isConnected(){return this.connection.connectionState==="connected"}async disconnect(){this.subscription&&(this.subscription=null),await this.connection.disconnect()}handleBroadcast(e){var n,i,c,l,h,u,g,m;const s=this.conversationManager.conversationId;switch(e.type){case"status":{const r=e.status;this.emit("status",r),(i=(n=this.config).onStatusChange)==null||i.call(n,r),r==="processing"&&this.emit("typing:start",void 0);break}case"error":{const r=new Error(e.message||"Unknown error");this.emit("error",r),(l=(c=this.config).onError)==null||l.call(c,r);break}case"message_start":{if(e.role==="assistant"){const r=this.messageStore.addStreamingMessage(s);this.emit("stream:start",{messageId:r.id}),this.emit("typing:start",void 0)}break}case"message_update":{const r=e.content||"",d=e.delta||"";this.messageStore.updateStreaming(r),this.emit("stream:update",{delta:d,content:r}),(u=(h=this.config).onStreamUpdate)==null||u.call(h,d,r);break}case"message_end":{const r=e.usage,d=this.messageStore.finalizeStreaming(r?{tokensInput:r.tokens_input||0,tokensOutput:r.tokens_output||0}:void 0);this.emit("typing:stop",void 0),d&&(this.emit("stream:end",{messageId:d.id,usage:r?{tokensInput:r.tokens_input||0,tokensOutput:r.tokens_output||0}:void 0}),this.emit("message:received",d),(m=(g=this.config).onMessage)==null||m.call(g,d));break}case"message_queued":{const r=this.messageStore.messages.findLast(d=>d.status==="sending");r&&this.messageStore.confirmOptimistic(r.id);break}case"tool_execution_start":case"tool_execution_update":case"tool_execution_end":case"agent_start":case"agent_end":case"turn_start":case"turn_end":case"auto_retry_start":case"auto_retry_end":case"cancelled":this.emit("status",e.type);break}}}exports.ActionCableClient=f;exports.AikaaraChatClient=N;exports.ApiClient=v;exports.ChannelSubscription=b;exports.ConnectionManager=S;exports.ConversationManager=w;exports.DEFAULT_BORDER_RADIUS=O;exports.DEFAULT_FONT_FAMILY=U;exports.DEFAULT_OFFSET=R;exports.DEFAULT_PLACEHOLDER=D;exports.DEFAULT_POSITION=F;exports.DEFAULT_PRIMARY_COLOR=M;exports.DEFAULT_THEME=L;exports.DEFAULT_WIDGET_HEIGHT=C;exports.DEFAULT_WIDGET_WIDTH=k;exports.EventEmitter=_;exports.MessageStore=y;
|