@aikaara/chat-sdk 1.1.13 → 1.1.14

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.
@@ -474,7 +474,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
474
474
  }
475
475
  </style>
476
476
  <div class="message-list"></div>
477
- `,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)return;if(this.container.innerHTML="",e.length===0&&this.welcomeMessage){this.container.innerHTML=`<div class="welcome">${Bt(Ut(this.welcomeMessage))}</div>`;return}const t=this.computeConsumedIds(e);for(const r of e){const i=r.externalId??r.id;this.appendMessageElement(r,t.get(i))}this.scrollToBottom()}computeConsumedIds(e){const t=new Map;let r=-1;for(let i=e.length-1;i>=0;i--)if(e[i].role==="user"){r=i;break}for(let i=0;i<e.length;i++){const n=e[i];if(n.role==="user"){const o=n.metadata?.attributes?.action;o?.message_id&&t.set(o.message_id,Od(o))}if(n.role!=="user"&&n.template?.contentType&&i<r){const o=n.externalId??n.id;t.has(o)||t.set(o,{})}}return t}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=Bt(Ut(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,t){if(e.role==="user"&&e.content?.trim()==="CHAT_INITIATED"||this.shouldHideMessage(e))return;if(e.role==="system"){if(!e.content||!e.content.trim())return;const c=document.createElement("div");c.classList.add("message-wrap","system"),c.dataset.messageId=e.id,e.externalId&&(c.dataset.externalId=e.externalId);const u=document.createElement("aikaara-system-pill");u.setAttribute("text",e.content),c.appendChild(u),this.container.appendChild(c);return}const r=document.createElement("div");r.classList.add("message-wrap",e.role),e.status==="streaming"&&r.setAttribute("data-streaming","true"),e.externalId&&(r.dataset.externalId=e.externalId),r.dataset.messageId=e.id;const i=document.createElement("div");i.classList.add("bubble",e.role);const o=!!e.template?.contentType&&e.role!=="user";e.role==="user"?!!e.attachments?.length&&!e.content?.trim()?i.classList.add("attachment-only"):i.textContent=e.content:o?e.content&&(i.innerHTML=Bt(Ut(e.content))):(i.innerHTML=Bt(Ut(e.content||"")),e.status==="streaming"&&i.classList.add("streaming-cursor"));let s=null;if(e.template?.contentType){const c=document.createElement("aikaara-template-renderer");c.setAttribute("content-type",e.template.contentType),e.template.templateId&&c.setAttribute("template-id",e.template.templateId);const u=e.externalId??e.id;u&&c.setAttribute("message-id",u),c.setPayload(e.template.payload),t!==void 0&&(c.dataset.consumed="true",Object.keys(t).length>0&&c.setConsumedValues?.(t)),this.templateLayout==="outside"?(c.classList.add("template-outside"),s=c):i.appendChild(c)}const a=e.template?.templateId==="7";if(e.attachments?.length&&!a){const c=document.createElement("div");c.classList.add("attachments");for(const u of e.attachments){const h=document.createElement("aikaara-template-renderer");h.setAttribute("content-type","300"),h.setAttribute("template-id","7");const p={elements:[{description:u.fileName,action:{url:u.fileUrl,type:"link",isDeepLink:!0}}]};h.setPayload(p,""),c.appendChild(h)}i.appendChild(c)}if(r.appendChild(i),s&&r.appendChild(s),this.showTimestamps&&(e.createdAt||e.role==="user"&&e.status)){const c=document.createElement("div");if(c.classList.add("timestamp"),this.showTimestamps&&e.createdAt&&(c.textContent=this.formatTime(e.createdAt)),e.role==="user"&&e.status){const u=document.createElement("span");u.classList.add("status-tick"),e.status==="read"&&u.classList.add("read"),u.textContent={sending:" ○",sent:" ✓",delivered:" ✓✓",read:" ✓✓"}[e.status]??"",c.appendChild(u)}r.appendChild(c)}this.container.appendChild(r)}upsertMessage(e){const t=this.findRenderedMessage(e);t&&t.remove(),this.appendMessageElement(e),this.scrollToBottom()}findRenderedMessage(e){if(e.externalId){const t=this.container.querySelector(`[data-external-id="${CSS.escape(e.externalId)}"]`);if(t)return t}return this.container.querySelector(`[data-message-id="${CSS.escape(e.id)}"]`)}scrollToBottom(){const e=()=>{this.scrollTop=this.scrollHeight,this.container.scrollTop=this.container.scrollHeight};requestAnimationFrame(()=>{e(),requestAnimationFrame(e)}),setTimeout(e,150)}formatTime(e){try{const t=new Date(e),r=t.toLocaleDateString(void 0,{month:"short",day:"2-digit"});switch(this.timestampFormat){case"datetime":return`${r}, ${t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"})}`;case"datetime-seconds":return`${r}, ${t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit"})}`;case"datetime-24":return`${r}, ${t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",hour12:!1})}`;case"date":return r;case"relative":return Cd(t);case"time-24":return t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",hour12:!1});case"time-seconds":return t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit"});case"none":return"";default:return t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"})}}catch{return""}}async handleLinkClick(e,t){const r=this.linkHandlers.find(y=>Pd(e,y.match)),i=r?.target??"iframe";if(i==="tab"){window.open(e,"_blank","noopener,noreferrer");return}const n=this.getOrCreateModal(),o=r?.title??t??"Link";if(i==="iframe"||!r?.fetch||!r.render){requestAnimationFrame(()=>n.show?.(e,o));return}const s=Md(e),a=ql(r.fetch.url,s),c={accept:"application/json",...r.fetch.headers??{}},u=r.fetch.authHeader??"session";if(u!=="none"&&this.getLinkBearer){const y=await this.getLinkBearer(u);y&&(c.authorization=`Bearer ${y}`)}const h={method:r.fetch.method??"GET",headers:c};r.fetch.body&&(c["content-type"]="application/json",h.body=JSON.stringify(eo(r.fetch.body,s)));let p=null;try{const y=await fetch(a,h);y.ok&&(p=await y.json().catch(()=>null))}catch(y){console.warn("[aikaara-chat-sdk] linkHandler fetch failed",y)}requestAnimationFrame(()=>{n.showElement?.(r.render,o,y=>{const f=r.props??{setData:p};for(const[b,k]of Object.entries(f)){const m=y[b];typeof m=="function"&&m.call(y,k)}const g=b=>{const k=b,m=k.detail?.message??k.detail?.label;m&&(n.close?.(),this.dispatchEvent(new CustomEvent("message-action",{detail:{text:m,attributes:{...k.detail?.attributes??{}}},bubbles:!0,composed:!0})))};y.addEventListener("aikaara-plan-select",g),y.addEventListener("aikaara-select",g)})})}getOrCreateModal(){let e=document.querySelector("aikaara-link-modal");return e||(e=document.createElement("aikaara-link-modal"),document.body.appendChild(e)),e}}function Od(l){const e=new Set(["message_id","formAction","requestType"]),t={};for(const[r,i]of Object.entries(l))e.has(r)||(Array.isArray(i)&&i.every(n=>typeof n=="string")?t[r]=i:typeof i=="string"&&(t[r]=[i]));return t}function Pd(l,e){const t=e.replace(/[.+^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+t.replace(/\*/g,".*").replace(/\?/g,".")+"$","i").test(l)}function Md(l){try{const e=new URL(l),t={};return e.searchParams.forEach((r,i)=>{t[i]=r}),t}catch{return{}}}function ql(l,e){return l.replace(/\{(\w+)\}/g,(t,r)=>e[r]??"")}function eo(l,e){if(typeof l=="string")return ql(l,e);if(Array.isArray(l))return l.map(t=>eo(t,e));if(l&&typeof l=="object"){const t={};for(const[r,i]of Object.entries(l))t[r]=eo(i,e);return t}return l}class Hl extends HTMLElement{shadow;templatePayload=null;attachments=[];static get observedAttributes(){return["role","content","timestamp","content-type","template-id","inner-message","message-id","status"]}constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}setTemplatePayload(e){this.templatePayload=e,this.render()}setAttachments(e){this.attachments=e,this.render()}render(){const e=this.getAttribute("role")||"user",t=this.getAttribute("content")||"",r=this.getAttribute("timestamp")||"",i=this.getAttribute("status")||"",n=this.getAttribute("content-type")||"",o=this.getAttribute("template-id")||"",s=this.getAttribute("inner-message")||"",a=e==="user"?document.createTextNode(t).textContent||"":Bt(Ut(t)),c=e==="user"&&i,u=i==="sending"?"○":i==="sent"?"✓":i==="delivered"||i==="read"?"✓✓":"";this.shadow.innerHTML=`
477
+ `,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)return;if(this.container.innerHTML="",e.length===0&&this.welcomeMessage){this.container.innerHTML=`<div class="welcome">${Bt(Ut(this.welcomeMessage))}</div>`;return}const t=this.computeConsumedIds(e);for(const r of e){const i=r.externalId??r.id;this.appendMessageElement(r,t.get(i))}this.scrollToBottom()}computeConsumedIds(e){const t=new Map;let r=-1;for(let i=e.length-1;i>=0;i--)if(e[i].role==="user"){r=i;break}for(let i=0;i<e.length;i++){const n=e[i];if(n.role==="user"){const o=n.metadata?.attributes?.action;if(o){const s=Od(o);if(o.message_id&&t.set(o.message_id,s),Object.keys(s).length>0)for(let a=i-1;a>=0;a--){const c=e[a];if(c.role!=="user"&&c.template?.contentType){const u=c.externalId??c.id,h=t.get(u);(!h||Object.keys(h).length===0)&&t.set(u,s);break}}}}if(n.role!=="user"&&n.template?.contentType&&i<r){const o=n.externalId??n.id;t.has(o)||t.set(o,{})}}return t}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=Bt(Ut(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,t){if(e.role==="user"&&e.content?.trim()==="CHAT_INITIATED"||this.shouldHideMessage(e))return;if(e.role==="system"){if(!e.content||!e.content.trim())return;const c=document.createElement("div");c.classList.add("message-wrap","system"),c.dataset.messageId=e.id,e.externalId&&(c.dataset.externalId=e.externalId);const u=document.createElement("aikaara-system-pill");u.setAttribute("text",e.content),c.appendChild(u),this.container.appendChild(c);return}const r=document.createElement("div");r.classList.add("message-wrap",e.role),e.status==="streaming"&&r.setAttribute("data-streaming","true"),e.externalId&&(r.dataset.externalId=e.externalId),r.dataset.messageId=e.id;const i=document.createElement("div");i.classList.add("bubble",e.role);const o=!!e.template?.contentType&&e.role!=="user";e.role==="user"?!!e.attachments?.length&&!e.content?.trim()?i.classList.add("attachment-only"):i.textContent=e.content:o?e.content&&(i.innerHTML=Bt(Ut(e.content))):(i.innerHTML=Bt(Ut(e.content||"")),e.status==="streaming"&&i.classList.add("streaming-cursor"));let s=null;if(e.template?.contentType){const c=document.createElement("aikaara-template-renderer");c.setAttribute("content-type",e.template.contentType),e.template.templateId&&c.setAttribute("template-id",e.template.templateId);const u=e.externalId??e.id;u&&c.setAttribute("message-id",u),c.setPayload(e.template.payload),t!==void 0&&(c.dataset.consumed="true",Object.keys(t).length>0&&c.setConsumedValues?.(t)),this.templateLayout==="outside"?(c.classList.add("template-outside"),s=c):i.appendChild(c)}const a=e.template?.templateId==="7";if(e.attachments?.length&&!a){const c=document.createElement("div");c.classList.add("attachments");for(const u of e.attachments){const h=document.createElement("aikaara-template-renderer");h.setAttribute("content-type","300"),h.setAttribute("template-id","7");const p={elements:[{description:u.fileName,action:{url:u.fileUrl,type:"link",isDeepLink:!0}}]};h.setPayload(p,""),c.appendChild(h)}i.appendChild(c)}if(r.appendChild(i),s&&r.appendChild(s),this.showTimestamps&&(e.createdAt||e.role==="user"&&e.status)){const c=document.createElement("div");if(c.classList.add("timestamp"),this.showTimestamps&&e.createdAt&&(c.textContent=this.formatTime(e.createdAt)),e.role==="user"&&e.status){const u=document.createElement("span");u.classList.add("status-tick"),e.status==="read"&&u.classList.add("read"),u.textContent={sending:" ○",sent:" ✓",delivered:" ✓✓",read:" ✓✓"}[e.status]??"",c.appendChild(u)}r.appendChild(c)}this.container.appendChild(r)}upsertMessage(e){const t=this.findRenderedMessage(e);t&&t.remove(),this.appendMessageElement(e),this.scrollToBottom()}findRenderedMessage(e){if(e.externalId){const t=this.container.querySelector(`[data-external-id="${CSS.escape(e.externalId)}"]`);if(t)return t}return this.container.querySelector(`[data-message-id="${CSS.escape(e.id)}"]`)}scrollToBottom(){const e=()=>{this.scrollTop=this.scrollHeight,this.container.scrollTop=this.container.scrollHeight};requestAnimationFrame(()=>{e(),requestAnimationFrame(e)}),setTimeout(e,150)}formatTime(e){try{const t=new Date(e),r=t.toLocaleDateString(void 0,{month:"short",day:"2-digit"});switch(this.timestampFormat){case"datetime":return`${r}, ${t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"})}`;case"datetime-seconds":return`${r}, ${t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit"})}`;case"datetime-24":return`${r}, ${t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",hour12:!1})}`;case"date":return r;case"relative":return Cd(t);case"time-24":return t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",hour12:!1});case"time-seconds":return t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit"});case"none":return"";default:return t.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"})}}catch{return""}}async handleLinkClick(e,t){const r=this.linkHandlers.find(y=>Pd(e,y.match)),i=r?.target??"iframe";if(i==="tab"){window.open(e,"_blank","noopener,noreferrer");return}const n=this.getOrCreateModal(),o=r?.title??t??"Link";if(i==="iframe"||!r?.fetch||!r.render){requestAnimationFrame(()=>n.show?.(e,o));return}const s=Md(e),a=ql(r.fetch.url,s),c={accept:"application/json",...r.fetch.headers??{}},u=r.fetch.authHeader??"session";if(u!=="none"&&this.getLinkBearer){const y=await this.getLinkBearer(u);y&&(c.authorization=`Bearer ${y}`)}const h={method:r.fetch.method??"GET",headers:c};r.fetch.body&&(c["content-type"]="application/json",h.body=JSON.stringify(eo(r.fetch.body,s)));let p=null;try{const y=await fetch(a,h);y.ok&&(p=await y.json().catch(()=>null))}catch(y){console.warn("[aikaara-chat-sdk] linkHandler fetch failed",y)}requestAnimationFrame(()=>{n.showElement?.(r.render,o,y=>{const f=r.props??{setData:p};for(const[b,k]of Object.entries(f)){const m=y[b];typeof m=="function"&&m.call(y,k)}const g=b=>{const k=b,m=k.detail?.message??k.detail?.label;m&&(n.close?.(),this.dispatchEvent(new CustomEvent("message-action",{detail:{text:m,attributes:{...k.detail?.attributes??{}}},bubbles:!0,composed:!0})))};y.addEventListener("aikaara-plan-select",g),y.addEventListener("aikaara-select",g)})})}getOrCreateModal(){let e=document.querySelector("aikaara-link-modal");return e||(e=document.createElement("aikaara-link-modal"),document.body.appendChild(e)),e}}function Od(l){const e=new Set(["message_id","formAction","requestType"]),t={};for(const[r,i]of Object.entries(l))e.has(r)||(Array.isArray(i)&&i.every(n=>typeof n=="string")?t[r]=i:typeof i=="string"&&(t[r]=[i]));return t}function Pd(l,e){const t=e.replace(/[.+^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+t.replace(/\*/g,".*").replace(/\?/g,".")+"$","i").test(l)}function Md(l){try{const e=new URL(l),t={};return e.searchParams.forEach((r,i)=>{t[i]=r}),t}catch{return{}}}function ql(l,e){return l.replace(/\{(\w+)\}/g,(t,r)=>e[r]??"")}function eo(l,e){if(typeof l=="string")return ql(l,e);if(Array.isArray(l))return l.map(t=>eo(t,e));if(l&&typeof l=="object"){const t={};for(const[r,i]of Object.entries(l))t[r]=eo(i,e);return t}return l}class Hl extends HTMLElement{shadow;templatePayload=null;attachments=[];static get observedAttributes(){return["role","content","timestamp","content-type","template-id","inner-message","message-id","status"]}constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}setTemplatePayload(e){this.templatePayload=e,this.render()}setAttachments(e){this.attachments=e,this.render()}render(){const e=this.getAttribute("role")||"user",t=this.getAttribute("content")||"",r=this.getAttribute("timestamp")||"",i=this.getAttribute("status")||"",n=this.getAttribute("content-type")||"",o=this.getAttribute("template-id")||"",s=this.getAttribute("inner-message")||"",a=e==="user"?document.createTextNode(t).textContent||"":Bt(Ut(t)),c=e==="user"&&i,u=i==="sending"?"○":i==="sent"?"✓":i==="delivered"||i==="read"?"✓✓":"";this.shadow.innerHTML=`
478
478
  <style>
479
479
  :host { display: flex; flex-direction: column; }
480
480
  :host([role="user"]) { align-items: flex-end; }
@@ -13590,8 +13590,7 @@ class sd extends HTMLElement {
13590
13590
  this.scrollToBottom();
13591
13591
  }
13592
13592
  // Returns a map of consumed bot-message-id → submitted form field values.
13593
- // Empty object value means consumed but no field values could be extracted
13594
- // (implicit consumption or quick-reply button without structured postback).
13593
+ // Empty object value means consumed but no field values could be extracted.
13595
13594
  computeConsumedIds(e) {
13596
13595
  const t = /* @__PURE__ */ new Map();
13597
13596
  let r = -1;
@@ -13604,7 +13603,18 @@ class sd extends HTMLElement {
13604
13603
  const n = e[i];
13605
13604
  if (n.role === "user") {
13606
13605
  const o = n.metadata?.attributes?.action;
13607
- o?.message_id && t.set(o.message_id, ad(o));
13606
+ if (o) {
13607
+ const s = ad(o);
13608
+ if (o.message_id && t.set(o.message_id, s), Object.keys(s).length > 0)
13609
+ for (let a = i - 1; a >= 0; a--) {
13610
+ const c = e[a];
13611
+ if (c.role !== "user" && c.template?.contentType) {
13612
+ const u = c.externalId ?? c.id, h = t.get(u);
13613
+ (!h || Object.keys(h).length === 0) && t.set(u, s);
13614
+ break;
13615
+ }
13616
+ }
13617
+ }
13608
13618
  }
13609
13619
  if (n.role !== "user" && n.template?.contentType && i < r) {
13610
13620
  const o = n.externalId ?? n.id;