@useago/sdk 0.4.3 → 0.4.5

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/widget.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ue=require("./AgoClient-D4EL6nva.cjs"),ge=require("./createFormCollector-Wb8Rr-U2.cjs"),xe=require("./createConversationSession-DtaeA418.cjs");var oe='var(--ago-font, "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif)',ee={font:"--ago-font",radius:"--ago-radius",brand:"--ago-brand-color",brandText:"--ago-brand-text-color",headerBg:"--ago-header-background",headerText:"--ago-header-text-color",panelBg:"--ago-panel-background",messagesBg:"--ago-messages-background",text:"--ago-text-color",mutedText:"--ago-muted-text-color",border:"--ago-border-color",accent:"--ago-accent-color"},ne="var(--ago-brand-color, #03182f)",re="var(--ago-brand-text-color, #fff)",me="var(--ago-header-background, var(--ago-brand-color, #03182f))",he="var(--ago-header-text-color, #e8f0fe)",L="var(--ago-panel-background, #fff)",be="var(--ago-messages-background, #fbfbfb)",z="var(--ago-text-color, #30373e)",Ce="var(--ago-muted-text-color, #6b6d6f)",E="var(--ago-border-color, #dee3e8)",G="var(--ago-accent-color, #1b5fc4)",K="var(--ago-radius, 16px)";function ve(i,o){if(o)for(const u of Object.keys(ee)){const w=o[u];w!=null&&i.style.setProperty(ee[u],w)}}function m(i,o){Object.assign(i.style,o)}function c(i={}){const o=document.createElement("div");return m(o,i),o}var te="ago-chat-widget-keyframes";function ye(){if(typeof document>"u"||document.getElementById(te))return;const i=document.createElement("style");i.id=te,i.textContent="@keyframes ago-pulse { 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); } 40% { opacity: 1; transform: scale(1); } }",document.head.appendChild(i)}function Ee(i){const o=typeof i=="string"?document.querySelector(i):i;if(!o)throw new Error(`mountChatWidget: target "${String(i)}" not found.`);return o}function we(i,o){const{title:u="Chat",welcomeMessage:w="Hello! How can I help you today?",placeholder:T="Type a message...",allowFiles:g=!1,height:x=500,logoUrl:f,showAgentName:C=!1,theme:A,loadThreads:D=!1,forms:B,onFollowUpClick:s,onMessageSent:v,onMessageReceived:$}=o;if(!o.client&&!o.config?.baseUrl)throw new Error("mountChatWidget requires either `client` or `config` (with a baseUrl).");const l=o.client??new ue.AgoClient(o.config),k=Ee(i),M=o.persistConversation,I=M?xe.createConversationSession(M===!0?{}:M):void 0;let h=o.conversationId??I?.getLastActiveThread()??void 0,n=[],_=!1,N=null;const U=[],O=c({display:"flex",flexDirection:"column",height:typeof x=="number"?`${x}px`:x,border:`1px solid ${E}`,borderRadius:K,overflow:"hidden",backgroundColor:L,fontFamily:oe,boxShadow:"rgba(15, 15, 15, 0.08) 0px 2px 16px 0px"});O.className="ago-chat-widget",ve(O,A);const W=c({padding:"14px 16px",borderBottom:`1px solid ${E}`,backgroundColor:me,color:he,display:"flex",alignItems:"center",gap:"10px"});if(W.className="ago-chat-widget__header",f){const e=document.createElement("img");e.src=f,e.alt="Logo",m(e,{height:"24px",width:"auto"}),W.appendChild(e)}const H=document.createElement("h3");H.textContent=u,m(H,{margin:"0",fontSize:"15px",fontWeight:"600"}),W.appendChild(H);const S=c({flex:"1",overflow:"auto",padding:"16px",backgroundColor:be});S.className="ago-chat-widget__messages";const{inputRow:ae,setDisabled:se,focus:ie}=Se({placeholder:T,allowFiles:g,onSend:(e,t)=>{F(e,t)}});ye(),O.append(W,S,ae),k.appendChild(O);const j=s!==!1,X=s===!1?void 0:s??(e=>{F(e)});function le(e){const t=e.role==="user",d=c({display:"flex",flexDirection:"column",alignItems:t?"flex-end":"flex-start",marginBottom:"16px"});if(d.className=`ago-message ago-message--${e.role}`,!t&&C&&e.agent){const r=c({fontSize:"13px",fontWeight:"500",color:z,marginBottom:"6px",padding:"0 4px"});r.className="ago-message__agent",r.textContent=e.agent.displayName||e.agent.name,d.appendChild(r)}if(!t&&e.sources&&e.sources.length>0){const r=c({display:"grid",gridTemplateColumns:"1fr 1fr",gap:"6px",marginBottom:"10px",width:"100%",maxWidth:"85%"});r.className="ago-message__sources",e.sources.forEach((p,a)=>{const y=p.url?document.createElement("a"):document.createElement("div");p.url&&y instanceof HTMLAnchorElement&&(y.href=p.url,y.target="_blank",y.rel="noopener noreferrer"),m(y,{display:"flex",alignItems:"center",gap:"8px",padding:"8px 10px",border:`1px solid ${E}`,borderRadius:"8px",backgroundColor:L,textDecoration:"none",color:z,fontSize:"12px",overflow:"hidden"});const Z=c({flexShrink:"0",width:"18px",height:"18px",borderRadius:"3px",border:`1px solid ${G}`,color:G,fontSize:"11px",fontWeight:"500",display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"#f0f4ff"});Z.textContent=String(a+1);const q=c({overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});q.textContent=p.title,q.title=p.title,y.append(Z,q),r.appendChild(y)}),d.appendChild(r)}const b=c({maxWidth:t?"75%":"100%",padding:t?"10px 14px":"2px 8px",borderRadius:t?K:"0",backgroundColor:t?ne:"transparent",color:t?re:z,wordBreak:"break-word",fontSize:"14px",lineHeight:"1.6",whiteSpace:"pre-wrap"});if(b.className="ago-message__content",e.content?b.textContent=e.content:e.status==="IN_PROGRESS"&&b.appendChild(fe()),d.appendChild(b),e.followUpReplies&&e.followUpReplies.length>0){const r=c({display:"flex",flexWrap:"wrap",gap:"8px",marginTop:"10px"});r.className="ago-message__followups";for(const p of e.followUpReplies){const a=document.createElement("button");a.type="button",a.className="ago-message__followup-btn",a.textContent=p,a.disabled=!j,m(a,{padding:"6px 14px",fontSize:"13px",borderRadius:K,border:`1px solid ${E}`,backgroundColor:L,color:z,cursor:j?"pointer":"default",transition:"border-color 0.15s"}),X&&a.addEventListener("click",()=>X(p)),a.addEventListener("mouseenter",()=>{a.style.borderColor=G}),a.addEventListener("mouseleave",()=>{a.style.borderColor=E}),r.appendChild(a)}d.appendChild(r)}return d}function R(){if(S.replaceChildren(),n.length===0){const e=c({textAlign:"center",color:Ce,padding:"24px 16px",fontSize:"14px",lineHeight:"1.5"});e.textContent=w,S.appendChild(e)}else for(const e of n)S.appendChild(le(e));if(N){const e=c({padding:"10px 14px",backgroundColor:"#fef2f2",color:"#dc2626",borderRadius:"12px",marginTop:"8px",fontSize:"13px",border:"1px solid #fecaca"});e.textContent=N,S.appendChild(e)}S.scrollTop=S.scrollHeight,se(_)}function de(){for(let e=n.length-1;e>=0;e--){const t=n[e];if(t.role==="assistant"&&t.status==="IN_PROGRESS")return t}}const V=e=>{h||(h=e.conversationId)},Y=e=>{const t=de();t&&(t.content+=e.content,R())},J=e=>{const t=n.findIndex(d=>d.id===e.id||d.role==="assistant"&&d.status==="IN_PROGRESS");t>=0?n[t]=e:n.push(e),_=!1,R(),e.status==="DONE"&&$?.({id:e.id,content:e.content})},Q=e=>{N=e.error,_=!1,n=n.filter(t=>!t.id.startsWith("temp-")),R()};l.on("message:start",V),l.on("message:chunk",Y),l.on("message:complete",J),l.on("message:error",Q);const ce=(B??[]).map(e=>ge.createFormCollector(e).install(l));async function F(e,t){const d=e.trim();if(!d&&!t?.length||_)return;v?.(d),_=!0,N=null;const b=Date.now();n.push({id:`temp-user-${b}`,conversationId:h||"",content:d,role:"user",status:"DONE",createdAt:new Date}),n.push({id:`temp-assistant-${b}`,conversationId:h||"",content:"",role:"assistant",status:"IN_PROGRESS",createdAt:new Date}),R();try{const r=await l.sendMessage(d,{conversationId:h,files:t});r.conversationId&&(h||(h=r.conversationId),I?.setActiveThread(r.conversationId,r.createdAt));const p=n.find(a=>a.id===`temp-user-${b}`);if(p&&(p.id=`user-${b}`,p.conversationId=r.conversationId),!n.some(a=>a.id===r.id)){const a=n.findIndex(y=>y.id===`temp-assistant-${b}`);a>=0?n[a]=r:n.push(r)}n=n.filter(a=>!a.id.startsWith("temp-")),_=!1,R(),D&&P()}catch(r){N=r instanceof Error?r.message:"Failed to send message",_=!1,n=n.filter(p=>!p.id.startsWith("temp-")),R()}}async function P(){try{const e=await l.getConversations();U.splice(0,U.length,...e)}catch{}return U}async function pe(e){try{const t=(await l.getConversation(e))?.messages??[];t.length>0&&n.length===0&&(n=t,R())}catch{n.length===0&&(I?.clear(),h=void 0)}}return R(),ie(),h&&pe(h),D&&P(),{client:l,element:O,sendMessage:F,session:I,threads:U,refreshThreads:P,destroy(){l.off("message:start",V),l.off("message:chunk",Y),l.off("message:complete",J),l.off("message:error",Q),ce.forEach(e=>e()),O.remove(),o.client||l.destroy()}};function fe(){const e=c({display:"flex",gap:"4px",padding:"4px 0"});for(let t=0;t<3;t++){const d=c({width:"6px",height:"6px",borderRadius:"50%",backgroundColor:"#b5bfc8",animation:"ago-pulse 1.2s ease-in-out infinite",animationDelay:`${t*.2}s`});e.appendChild(d)}return e}}function Se(i){let o=[];const u=document.createElement("form");m(u,{display:"flex",flexDirection:"column",gap:"8px",padding:"12px",borderTop:`1px solid ${E}`,backgroundColor:L}),u.className="ago-chat-input";const w=c({display:"flex",flexWrap:"wrap",gap:"6px"}),T=c({display:"flex",gap:"8px",alignItems:"flex-end"}),g=document.createElement("textarea");g.placeholder=i.placeholder,g.rows=1,m(g,{flex:"1",resize:"none",padding:"10px 12px",border:`1px solid ${E}`,borderRadius:"12px",fontSize:"14px",fontFamily:oe,lineHeight:"1.4",maxHeight:"120px",outline:"none"});const x=document.createElement("button");x.type="submit",x.textContent="Send",m(x,{padding:"10px 16px",border:"none",borderRadius:"12px",backgroundColor:ne,color:re,fontSize:"14px",fontWeight:"500",cursor:"pointer"});let f=null,C=null;i.allowFiles&&(f=document.createElement("input"),f.type="file",f.multiple=!0,m(f,{display:"none"}),C=document.createElement("button"),C.type="button",C.textContent="📎",m(C,{padding:"10px 12px",border:`1px solid ${E}`,borderRadius:"12px",backgroundColor:L,cursor:"pointer",fontSize:"14px"}),C.addEventListener("click",()=>f?.click()),f.addEventListener("change",()=>{o=[...o,...Array.from(f?.files??[])],A()}));function A(){w.replaceChildren(),o.forEach((s,v)=>{const $=c({display:"flex",alignItems:"center",gap:"4px",padding:"4px 8px",backgroundColor:"#f0f4ff",border:`1px solid ${E}`,borderRadius:"8px",fontSize:"12px"}),l=document.createElement("span");l.textContent=s.name;const k=document.createElement("button");k.type="button",k.textContent="×",m(k,{border:"none",background:"transparent",cursor:"pointer",fontSize:"14px",lineHeight:"1"}),k.addEventListener("click",()=>{o=o.filter((M,I)=>I!==v),A()}),$.append(l,k),w.appendChild($)})}const D=()=>{const s=g.value,v=o;return g.value="",o=[],A(),{content:s,files:v}},B=()=>{const{content:s,files:v}=D();(s.trim()||v.length>0)&&i.onSend(s.trim(),v.length>0?v:void 0)};return u.addEventListener("submit",s=>{s.preventDefault(),B()}),g.addEventListener("keydown",s=>{s.key==="Enter"&&!s.shiftKey&&(s.preventDefault(),B())}),C&&T.appendChild(C),T.append(g,x),f&&u.appendChild(f),u.append(w,T),{inputRow:u,getValueAndClear:D,setDisabled:s=>{g.disabled=s,x.disabled=s,x.style.opacity=s?"0.6":"1",x.style.cursor=s?"not-allowed":"pointer"},focus:()=>g.focus()}}exports.mountChatWidget=we;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ue=require("./AgoClient-D4EL6nva.cjs"),ge=require("./createFormCollector-BMTdfhHg.cjs"),xe=require("./createConversationSession-0F_OXdQB.cjs");var oe='var(--ago-font, "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif)',Z={font:"--ago-font",radius:"--ago-radius",messageRadius:"--ago-message-radius",brand:"--ago-brand-color",brandText:"--ago-brand-text-color",headerBg:"--ago-header-background",headerText:"--ago-header-text-color",panelBg:"--ago-panel-background",messagesBg:"--ago-messages-background",text:"--ago-text-color",mutedText:"--ago-muted-text-color",border:"--ago-border-color",accent:"--ago-accent-color"},ne="var(--ago-brand-color, #03182f)",re="var(--ago-brand-text-color, #fff)",me="var(--ago-header-background, var(--ago-brand-color, #03182f))",he="var(--ago-header-text-color, #e8f0fe)",L="var(--ago-panel-background, #fff)",be="var(--ago-messages-background, #fbfbfb)",z="var(--ago-text-color, #30373e)",ve="var(--ago-muted-text-color, #6b6d6f)",E="var(--ago-border-color, #dee3e8)",q="var(--ago-accent-color, #1b5fc4)",Ce="var(--ago-radius, 16px)",ee="var(--ago-message-radius, 16px)";function ye(i,o){if(o)for(const u of Object.keys(Z)){const w=o[u];w!=null&&i.style.setProperty(Z[u],w)}}function m(i,o){Object.assign(i.style,o)}function c(i={}){const o=document.createElement("div");return m(o,i),o}var te="ago-chat-widget-keyframes";function Ee(){if(typeof document>"u"||document.getElementById(te))return;const i=document.createElement("style");i.id=te,i.textContent="@keyframes ago-pulse { 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); } 40% { opacity: 1; transform: scale(1); } }",document.head.appendChild(i)}function we(i){const o=typeof i=="string"?document.querySelector(i):i;if(!o)throw new Error(`mountChatWidget: target "${String(i)}" not found.`);return o}function Se(i,o){const{title:u="Chat",welcomeMessage:w="Hello! How can I help you today?",placeholder:O="Type a message...",allowFiles:g=!1,height:x=500,logoUrl:f,showAgentName:v=!1,theme:T,loadThreads:D=!1,forms:B,onFollowUpClick:s,onMessageSent:C,onMessageReceived:$}=o;if(!o.client&&!o.config?.baseUrl)throw new Error("mountChatWidget requires either `client` or `config` (with a baseUrl).");const l=o.client??new ue.AgoClient(o.config),_=we(i),M=o.persistConversation,I=M?xe.createConversationSession(M===!0?{}:M):void 0;let h=o.conversationId??I?.getLastActiveThread()??void 0,n=[],k=!1,N=null;const U=[],A=c({display:"flex",flexDirection:"column",height:typeof x=="number"?`${x}px`:x,border:`1px solid ${E}`,borderRadius:Ce,overflow:"hidden",backgroundColor:L,fontFamily:oe,textAlign:"left",boxShadow:"rgba(15, 15, 15, 0.08) 0px 2px 16px 0px"});A.className="ago-chat-widget",ye(A,T);const W=c({padding:"14px 16px",borderBottom:`1px solid ${E}`,backgroundColor:me,color:he,display:"flex",alignItems:"center",gap:"10px"});if(W.className="ago-chat-widget__header",f){const e=document.createElement("img");e.src=f,e.alt="Logo",m(e,{height:"24px",width:"auto"}),W.appendChild(e)}const H=document.createElement("h3");H.textContent=u,m(H,{margin:"0",fontSize:"15px",fontWeight:"600"}),W.appendChild(H);const S=c({flex:"1",overflow:"auto",padding:"16px",backgroundColor:be});S.className="ago-chat-widget__messages";const{inputRow:ae,setDisabled:se,focus:ie}=Re({placeholder:O,allowFiles:g,onSend:(e,t)=>{F(e,t)}});Ee(),A.append(W,S,ae),_.appendChild(A);const K=s!==!1,j=s===!1?void 0:s??(e=>{F(e)});function le(e){const t=e.role==="user",d=c({display:"flex",flexDirection:"column",alignItems:t?"flex-end":"flex-start",marginBottom:"16px"});if(d.className=`ago-message ago-message--${e.role}`,!t&&v&&e.agent){const r=c({fontSize:"13px",fontWeight:"500",color:z,marginBottom:"6px",padding:"0 4px"});r.className="ago-message__agent",r.textContent=e.agent.displayName||e.agent.name,d.appendChild(r)}if(!t&&e.sources&&e.sources.length>0){const r=c({display:"grid",gridTemplateColumns:"1fr 1fr",gap:"6px",marginBottom:"10px",width:"100%",maxWidth:"85%"});r.className="ago-message__sources",e.sources.forEach((p,a)=>{const y=p.url?document.createElement("a"):document.createElement("div");p.url&&y instanceof HTMLAnchorElement&&(y.href=p.url,y.target="_blank",y.rel="noopener noreferrer"),m(y,{display:"flex",alignItems:"center",gap:"8px",padding:"8px 10px",border:`1px solid ${E}`,borderRadius:"8px",backgroundColor:L,textDecoration:"none",color:z,fontSize:"12px",overflow:"hidden"});const Q=c({flexShrink:"0",width:"18px",height:"18px",borderRadius:"3px",border:`1px solid ${q}`,color:q,fontSize:"11px",fontWeight:"500",display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"#f0f4ff"});Q.textContent=String(a+1);const P=c({overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});P.textContent=p.title,P.title=p.title,y.append(Q,P),r.appendChild(y)}),d.appendChild(r)}const b=c({maxWidth:t?"75%":"100%",padding:t?"10px 14px":"2px 8px",borderRadius:t?ee:"0",backgroundColor:t?ne:"transparent",color:t?re:z,wordBreak:"break-word",fontSize:"14px",lineHeight:"1.6",whiteSpace:"pre-wrap"});if(b.className="ago-message__content",e.content?b.textContent=e.content:e.status==="IN_PROGRESS"&&b.appendChild(fe()),d.appendChild(b),e.followUpReplies&&e.followUpReplies.length>0){const r=c({display:"flex",flexWrap:"wrap",gap:"8px",marginTop:"10px"});r.className="ago-message__followups";for(const p of e.followUpReplies){const a=document.createElement("button");a.type="button",a.className="ago-message__followup-btn",a.textContent=p,a.disabled=!K,m(a,{padding:"6px 14px",fontSize:"13px",borderRadius:ee,border:`1px solid ${E}`,backgroundColor:L,color:z,cursor:K?"pointer":"default",transition:"border-color 0.15s"}),j&&a.addEventListener("click",()=>j(p)),a.addEventListener("mouseenter",()=>{a.style.borderColor=q}),a.addEventListener("mouseleave",()=>{a.style.borderColor=E}),r.appendChild(a)}d.appendChild(r)}return d}function R(){if(S.replaceChildren(),n.length===0){const e=c({textAlign:"center",color:ve,padding:"24px 16px",fontSize:"14px",lineHeight:"1.5"});e.textContent=w,S.appendChild(e)}else for(const e of n)S.appendChild(le(e));if(N){const e=c({padding:"10px 14px",backgroundColor:"#fef2f2",color:"#dc2626",borderRadius:"12px",marginTop:"8px",fontSize:"13px",border:"1px solid #fecaca"});e.textContent=N,S.appendChild(e)}S.scrollTop=S.scrollHeight,se(k)}function de(){for(let e=n.length-1;e>=0;e--){const t=n[e];if(t.role==="assistant"&&t.status==="IN_PROGRESS")return t}}const X=e=>{h||(h=e.conversationId)},V=e=>{const t=de();t&&(t.content+=e.content,R())},Y=e=>{const t=n.findIndex(d=>d.id===e.id||d.role==="assistant"&&d.status==="IN_PROGRESS");t>=0?n[t]=e:n.push(e),k=!1,R(),e.status==="DONE"&&$?.({id:e.id,content:e.content})},J=e=>{N=e.error,k=!1,n=n.filter(t=>!t.id.startsWith("temp-")),R()};l.on("message:start",X),l.on("message:chunk",V),l.on("message:complete",Y),l.on("message:error",J);const ce=(B??[]).map(e=>ge.createFormCollector(e).install(l));async function F(e,t){const d=e.trim();if(!d&&!t?.length||k)return;C?.(d),k=!0,N=null;const b=Date.now();n.push({id:`temp-user-${b}`,conversationId:h||"",content:d,role:"user",status:"DONE",createdAt:new Date}),n.push({id:`temp-assistant-${b}`,conversationId:h||"",content:"",role:"assistant",status:"IN_PROGRESS",createdAt:new Date}),R();try{const r=await l.sendMessage(d,{conversationId:h,files:t});r.conversationId&&(h||(h=r.conversationId),I?.setActiveThread(r.conversationId,r.createdAt));const p=n.find(a=>a.id===`temp-user-${b}`);if(p&&(p.id=`user-${b}`,p.conversationId=r.conversationId),!n.some(a=>a.id===r.id)){const a=n.findIndex(y=>y.id===`temp-assistant-${b}`);a>=0?n[a]=r:n.push(r)}n=n.filter(a=>!a.id.startsWith("temp-")),k=!1,R(),D&&G()}catch(r){N=r instanceof Error?r.message:"Failed to send message",k=!1,n=n.filter(p=>!p.id.startsWith("temp-")),R()}}async function G(){try{const e=await l.getConversations();U.splice(0,U.length,...e)}catch{}return U}async function pe(e){try{const t=(await l.getConversation(e))?.messages??[];t.length>0&&n.length===0&&(n=t,R())}catch{n.length===0&&(I?.clear(),h=void 0)}}return R(),ie(),h&&pe(h),D&&G(),{client:l,element:A,sendMessage:F,session:I,threads:U,refreshThreads:G,destroy(){l.off("message:start",X),l.off("message:chunk",V),l.off("message:complete",Y),l.off("message:error",J),ce.forEach(e=>e()),A.remove(),o.client||l.destroy()}};function fe(){const e=c({display:"flex",gap:"4px",padding:"4px 0"});for(let t=0;t<3;t++){const d=c({width:"6px",height:"6px",borderRadius:"50%",backgroundColor:"#b5bfc8",animation:"ago-pulse 1.2s ease-in-out infinite",animationDelay:`${t*.2}s`});e.appendChild(d)}return e}}function Re(i){let o=[];const u=document.createElement("form");m(u,{display:"flex",flexDirection:"column",gap:"8px",padding:"12px",borderTop:`1px solid ${E}`,backgroundColor:L}),u.className="ago-chat-input";const w=c({display:"flex",flexWrap:"wrap",gap:"6px"}),O=c({display:"flex",gap:"8px",alignItems:"flex-end"}),g=document.createElement("textarea");g.placeholder=i.placeholder,g.rows=1,m(g,{flex:"1",resize:"none",padding:"10px 12px",border:`1px solid ${E}`,borderRadius:"12px",fontSize:"14px",fontFamily:oe,lineHeight:"1.4",maxHeight:"120px",outline:"none"});const x=document.createElement("button");x.type="submit",x.textContent="Send",m(x,{padding:"10px 16px",border:"none",borderRadius:"12px",backgroundColor:ne,color:re,fontSize:"14px",fontWeight:"500",cursor:"pointer"});let f=null,v=null;i.allowFiles&&(f=document.createElement("input"),f.type="file",f.multiple=!0,m(f,{display:"none"}),v=document.createElement("button"),v.type="button",v.textContent="📎",m(v,{padding:"10px 12px",border:`1px solid ${E}`,borderRadius:"12px",backgroundColor:L,cursor:"pointer",fontSize:"14px"}),v.addEventListener("click",()=>f?.click()),f.addEventListener("change",()=>{o=[...o,...Array.from(f?.files??[])],T()}));function T(){w.replaceChildren(),o.forEach((s,C)=>{const $=c({display:"flex",alignItems:"center",gap:"4px",padding:"4px 8px",backgroundColor:"#f0f4ff",border:`1px solid ${E}`,borderRadius:"8px",fontSize:"12px"}),l=document.createElement("span");l.textContent=s.name;const _=document.createElement("button");_.type="button",_.textContent="×",m(_,{border:"none",background:"transparent",cursor:"pointer",fontSize:"14px",lineHeight:"1"}),_.addEventListener("click",()=>{o=o.filter((M,I)=>I!==C),T()}),$.append(l,_),w.appendChild($)})}const D=()=>{const s=g.value,C=o;return g.value="",o=[],T(),{content:s,files:C}},B=()=>{const{content:s,files:C}=D();(s.trim()||C.length>0)&&i.onSend(s.trim(),C.length>0?C:void 0)};return u.addEventListener("submit",s=>{s.preventDefault(),B()}),g.addEventListener("keydown",s=>{s.key==="Enter"&&!s.shiftKey&&(s.preventDefault(),B())}),v&&O.appendChild(v),O.append(g,x),f&&u.appendChild(f),u.append(w,O),{inputRow:u,getValueAndClear:D,setDisabled:s=>{g.disabled=s,x.disabled=s,x.style.opacity=s?"0.6":"1",x.style.cursor=s?"not-allowed":"pointer"},focus:()=>g.focus()}}exports.mountChatWidget=Se;
package/dist/widget.d.cts CHANGED
@@ -516,11 +516,14 @@ export declare interface CreateFormCollectorOptions<V = Record<string, unknown>>
516
516
  declare type DynamicContextProvider = () => ContextEntry | null | undefined;
517
517
 
518
518
  /**
519
- * JSON-schema shape of a form's fields — identical to a client function's
520
- * `parameters`, so one schema feeds the store, the update function, and the
521
- * dynamic context with no second type.
519
+ * Shape of a form's fields. Mirrors a client function's `parameters` (so the same
520
+ * object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes before the schema reaches the LLM.
522
521
  */
523
- declare type FormCollectorSchema = ClientFunctionSchema["parameters"];
522
+ declare interface FormCollectorSchema {
523
+ type: "object";
524
+ properties: Record<string, FormFieldSchema>;
525
+ required?: string[];
526
+ }
524
527
 
525
528
  declare interface FormField {
526
529
  type: "string" | "number" | "boolean" | "array";
@@ -530,6 +533,43 @@ declare interface FormField {
530
533
  default?: unknown;
531
534
  }
532
535
 
536
+ /**
537
+ * A field's conditional-requiredness rule. The field becomes required exactly
538
+ * when the controlling `property` matches `value` against the answers collected
539
+ * so far:
540
+ * - a single `value`, no `op` — equality (compared as strings);
541
+ * - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
542
+ * - an array `value`, no `op` — "one of": matches when the property equals any
543
+ * listed value.
544
+ *
545
+ * SDK-only — it is stripped from the schema before it reaches the LLM tool
546
+ */
547
+ declare interface FormFieldCondition {
548
+ /** The controlling field whose value the rule tests. */
549
+ property: string;
550
+ /** Comparison operator; omitted means equality. Ignored when `value` is an array. */
551
+ op?: ">=" | "<=" | ">" | "<";
552
+ /**
553
+ * The value(s) to test the controlling field against. A single value is an
554
+ * equality (or, with `op`, a numeric comparison); an array is an "is one of"
555
+ * membership test, e.g. `value: ["1", "2", "3"]`.
556
+ */
557
+ value: string | number | Array<string | number>;
558
+ }
559
+
560
+ /** A single field's schema: the wire-legal keys plus the SDK-only `requiredWhen`. */
561
+ declare interface FormFieldSchema {
562
+ type: string;
563
+ description?: string;
564
+ enum?: string[];
565
+ default?: unknown;
566
+ /**
567
+ * Makes the field required only while this condition holds. Drives the dynamic
568
+ * `missing` list; stripped before the LLM tool — see {@link toWireParameters}.
569
+ */
570
+ requiredWhen?: FormFieldCondition;
571
+ }
572
+
533
573
  /**
534
574
  * Form schema for tool calls requiring user input
535
575
  */
@@ -699,8 +739,10 @@ declare type ToolCallType = "form" | "confirmation_input" | "status_message" | "
699
739
  export declare interface WidgetTheme {
700
740
  /** Font family for the whole panel. Pass `"inherit"` to adopt the page font. (`--ago-font`) */
701
741
  font?: string;
702
- /** Corner radius of the panel, user bubbles, and suggested-reply pills. (`--ago-radius`) */
742
+ /** Corner radius of the panel container. (`--ago-radius`) */
703
743
  radius?: string;
744
+ /** Corner radius of message bubbles and suggested-reply pills. Defaults to 16px. (`--ago-message-radius`) */
745
+ messageRadius?: string;
704
746
  /** Brand color: user message bubbles and the send button (and the header, unless `headerBg` is set). (`--ago-brand-color`) */
705
747
  brand?: string;
706
748
  /** Text/icon color shown on top of `brand`. (`--ago-brand-text-color`) */
package/dist/widget.d.ts CHANGED
@@ -516,11 +516,14 @@ export declare interface CreateFormCollectorOptions<V = Record<string, unknown>>
516
516
  declare type DynamicContextProvider = () => ContextEntry | null | undefined;
517
517
 
518
518
  /**
519
- * JSON-schema shape of a form's fields — identical to a client function's
520
- * `parameters`, so one schema feeds the store, the update function, and the
521
- * dynamic context with no second type.
519
+ * Shape of a form's fields. Mirrors a client function's `parameters` (so the same
520
+ * object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes before the schema reaches the LLM.
522
521
  */
523
- declare type FormCollectorSchema = ClientFunctionSchema["parameters"];
522
+ declare interface FormCollectorSchema {
523
+ type: "object";
524
+ properties: Record<string, FormFieldSchema>;
525
+ required?: string[];
526
+ }
524
527
 
525
528
  declare interface FormField {
526
529
  type: "string" | "number" | "boolean" | "array";
@@ -530,6 +533,43 @@ declare interface FormField {
530
533
  default?: unknown;
531
534
  }
532
535
 
536
+ /**
537
+ * A field's conditional-requiredness rule. The field becomes required exactly
538
+ * when the controlling `property` matches `value` against the answers collected
539
+ * so far:
540
+ * - a single `value`, no `op` — equality (compared as strings);
541
+ * - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
542
+ * - an array `value`, no `op` — "one of": matches when the property equals any
543
+ * listed value.
544
+ *
545
+ * SDK-only — it is stripped from the schema before it reaches the LLM tool
546
+ */
547
+ declare interface FormFieldCondition {
548
+ /** The controlling field whose value the rule tests. */
549
+ property: string;
550
+ /** Comparison operator; omitted means equality. Ignored when `value` is an array. */
551
+ op?: ">=" | "<=" | ">" | "<";
552
+ /**
553
+ * The value(s) to test the controlling field against. A single value is an
554
+ * equality (or, with `op`, a numeric comparison); an array is an "is one of"
555
+ * membership test, e.g. `value: ["1", "2", "3"]`.
556
+ */
557
+ value: string | number | Array<string | number>;
558
+ }
559
+
560
+ /** A single field's schema: the wire-legal keys plus the SDK-only `requiredWhen`. */
561
+ declare interface FormFieldSchema {
562
+ type: string;
563
+ description?: string;
564
+ enum?: string[];
565
+ default?: unknown;
566
+ /**
567
+ * Makes the field required only while this condition holds. Drives the dynamic
568
+ * `missing` list; stripped before the LLM tool — see {@link toWireParameters}.
569
+ */
570
+ requiredWhen?: FormFieldCondition;
571
+ }
572
+
533
573
  /**
534
574
  * Form schema for tool calls requiring user input
535
575
  */
@@ -699,8 +739,10 @@ declare type ToolCallType = "form" | "confirmation_input" | "status_message" | "
699
739
  export declare interface WidgetTheme {
700
740
  /** Font family for the whole panel. Pass `"inherit"` to adopt the page font. (`--ago-font`) */
701
741
  font?: string;
702
- /** Corner radius of the panel, user bubbles, and suggested-reply pills. (`--ago-radius`) */
742
+ /** Corner radius of the panel container. (`--ago-radius`) */
703
743
  radius?: string;
744
+ /** Corner radius of message bubbles and suggested-reply pills. Defaults to 16px. (`--ago-message-radius`) */
745
+ messageRadius?: string;
704
746
  /** Brand color: user message bubbles and the send button (and the header, unless `headerBg` is set). (`--ago-brand-color`) */
705
747
  brand?: string;
706
748
  /** Text/icon color shown on top of `brand`. (`--ago-brand-text-color`) */
package/dist/widget.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { t as ge } from "./AgoClient-rvTz2thR.js";
2
- import { t as ue } from "./createFormCollector-BwvkKi48.js";
3
- import { t as xe } from "./createConversationSession-D9FesBQS.js";
4
- var oe = 'var(--ago-font, "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif)', ee = {
2
+ import { t as ue } from "./createFormCollector-Cujr7hW4.js";
3
+ import { t as xe } from "./createConversationSession-DbuVzvoX.js";
4
+ var oe = 'var(--ago-font, "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif)', Z = {
5
5
  font: "--ago-font",
6
6
  radius: "--ago-radius",
7
+ messageRadius: "--ago-message-radius",
7
8
  brand: "--ago-brand-color",
8
9
  brandText: "--ago-brand-text-color",
9
10
  headerBg: "--ago-header-background",
@@ -14,12 +15,12 @@ var oe = 'var(--ago-font, "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "S
14
15
  mutedText: "--ago-muted-text-color",
15
16
  border: "--ago-border-color",
16
17
  accent: "--ago-accent-color"
17
- }, ne = "var(--ago-brand-color, #03182f)", re = "var(--ago-brand-text-color, #fff)", me = "var(--ago-header-background, var(--ago-brand-color, #03182f))", he = "var(--ago-header-text-color, #e8f0fe)", L = "var(--ago-panel-background, #fff)", be = "var(--ago-messages-background, #fbfbfb)", H = "var(--ago-text-color, #30373e)", ve = "var(--ago-muted-text-color, #6b6d6f)", E = "var(--ago-border-color, #dee3e8)", K = "var(--ago-accent-color, #1b5fc4)", X = "var(--ago-radius, 16px)";
18
- function Ce(i, o) {
18
+ }, ne = "var(--ago-brand-color, #03182f)", re = "var(--ago-brand-text-color, #fff)", me = "var(--ago-header-background, var(--ago-brand-color, #03182f))", he = "var(--ago-header-text-color, #e8f0fe)", L = "var(--ago-panel-background, #fff)", be = "var(--ago-messages-background, #fbfbfb)", H = "var(--ago-text-color, #30373e)", ve = "var(--ago-muted-text-color, #6b6d6f)", E = "var(--ago-border-color, #dee3e8)", K = "var(--ago-accent-color, #1b5fc4)", Ce = "var(--ago-radius, 16px)", ee = "var(--ago-message-radius, 16px)";
19
+ function ye(i, o) {
19
20
  if (o)
20
- for (const g of Object.keys(ee)) {
21
+ for (const g of Object.keys(Z)) {
21
22
  const w = o[g];
22
- w != null && i.style.setProperty(ee[g], w);
23
+ w != null && i.style.setProperty(Z[g], w);
23
24
  }
24
25
  }
25
26
  function m(i, o) {
@@ -30,33 +31,34 @@ function c(i = {}) {
30
31
  return m(o, i), o;
31
32
  }
32
33
  var te = "ago-chat-widget-keyframes";
33
- function ye() {
34
+ function Ee() {
34
35
  if (typeof document > "u" || document.getElementById(te)) return;
35
36
  const i = document.createElement("style");
36
37
  i.id = te, i.textContent = "@keyframes ago-pulse { 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); } 40% { opacity: 1; transform: scale(1); } }", document.head.appendChild(i);
37
38
  }
38
- function Ee(i) {
39
+ function we(i) {
39
40
  const o = typeof i == "string" ? document.querySelector(i) : i;
40
41
  if (!o) throw new Error(`mountChatWidget: target "${String(i)}" not found.`);
41
42
  return o;
42
43
  }
43
- function _e(i, o) {
44
- const { title: g = "Chat", welcomeMessage: w = "Hello! How can I help you today?", placeholder: T = "Type a message...", allowFiles: u = !1, height: x = 500, logoUrl: f, showAgentName: v = !1, theme: A, loadThreads: D = !1, forms: B, onFollowUpClick: s, onMessageSent: C, onMessageReceived: $ } = o;
44
+ function Ie(i, o) {
45
+ const { title: g = "Chat", welcomeMessage: w = "Hello! How can I help you today?", placeholder: O = "Type a message...", allowFiles: u = !1, height: x = 500, logoUrl: f, showAgentName: v = !1, theme: T, loadThreads: D = !1, forms: B, onFollowUpClick: s, onMessageSent: C, onMessageReceived: $ } = o;
45
46
  if (!o.client && !o.config?.baseUrl) throw new Error("mountChatWidget requires either `client` or `config` (with a baseUrl).");
46
- const l = o.client ?? new ge(o.config), k = Ee(i), U = o.persistConversation, I = U ? xe(U === !0 ? {} : U) : void 0;
47
+ const l = o.client ?? new ge(o.config), k = we(i), U = o.persistConversation, I = U ? xe(U === !0 ? {} : U) : void 0;
47
48
  let h = o.conversationId ?? I?.getLastActiveThread() ?? void 0, n = [], _ = !1, N = null;
48
- const M = [], O = c({
49
+ const M = [], A = c({
49
50
  display: "flex",
50
51
  flexDirection: "column",
51
52
  height: typeof x == "number" ? `${x}px` : x,
52
53
  border: `1px solid ${E}`,
53
- borderRadius: X,
54
+ borderRadius: Ce,
54
55
  overflow: "hidden",
55
56
  backgroundColor: L,
56
57
  fontFamily: oe,
58
+ textAlign: "left",
57
59
  boxShadow: "rgba(15, 15, 15, 0.08) 0px 2px 16px 0px"
58
60
  });
59
- O.className = "ago-chat-widget", Ce(O, A);
61
+ A.className = "ago-chat-widget", ye(A, T);
60
62
  const z = c({
61
63
  padding: "14px 16px",
62
64
  borderBottom: `1px solid ${E}`,
@@ -86,15 +88,15 @@ function _e(i, o) {
86
88
  backgroundColor: be
87
89
  });
88
90
  R.className = "ago-chat-widget__messages";
89
- const { inputRow: ae, setDisabled: se, focus: ie } = we({
90
- placeholder: T,
91
+ const { inputRow: ae, setDisabled: se, focus: ie } = Re({
92
+ placeholder: O,
91
93
  allowFiles: u,
92
94
  onSend: (e, t) => {
93
95
  F(e, t);
94
96
  }
95
97
  });
96
- ye(), O.append(z, R, ae), k.appendChild(O);
97
- const j = s !== !1, V = s === !1 ? void 0 : s ?? ((e) => {
98
+ Ee(), A.append(z, R, ae), k.appendChild(A);
99
+ const X = s !== !1, j = s === !1 ? void 0 : s ?? ((e) => {
98
100
  F(e);
99
101
  });
100
102
  function le(e) {
@@ -138,7 +140,7 @@ function _e(i, o) {
138
140
  fontSize: "12px",
139
141
  overflow: "hidden"
140
142
  });
141
- const Z = c({
143
+ const Q = c({
142
144
  flexShrink: "0",
143
145
  width: "18px",
144
146
  height: "18px",
@@ -152,19 +154,19 @@ function _e(i, o) {
152
154
  justifyContent: "center",
153
155
  backgroundColor: "#f0f4ff"
154
156
  });
155
- Z.textContent = String(a + 1);
157
+ Q.textContent = String(a + 1);
156
158
  const P = c({
157
159
  overflow: "hidden",
158
160
  textOverflow: "ellipsis",
159
161
  whiteSpace: "nowrap"
160
162
  });
161
- P.textContent = p.title, P.title = p.title, y.append(Z, P), r.appendChild(y);
163
+ P.textContent = p.title, P.title = p.title, y.append(Q, P), r.appendChild(y);
162
164
  }), d.appendChild(r);
163
165
  }
164
166
  const b = c({
165
167
  maxWidth: t ? "75%" : "100%",
166
168
  padding: t ? "10px 14px" : "2px 8px",
167
- borderRadius: t ? X : "0",
169
+ borderRadius: t ? ee : "0",
168
170
  backgroundColor: t ? ne : "transparent",
169
171
  color: t ? re : H,
170
172
  wordBreak: "break-word",
@@ -182,16 +184,16 @@ function _e(i, o) {
182
184
  r.className = "ago-message__followups";
183
185
  for (const p of e.followUpReplies) {
184
186
  const a = document.createElement("button");
185
- a.type = "button", a.className = "ago-message__followup-btn", a.textContent = p, a.disabled = !j, m(a, {
187
+ a.type = "button", a.className = "ago-message__followup-btn", a.textContent = p, a.disabled = !X, m(a, {
186
188
  padding: "6px 14px",
187
189
  fontSize: "13px",
188
- borderRadius: X,
190
+ borderRadius: ee,
189
191
  border: `1px solid ${E}`,
190
192
  backgroundColor: L,
191
193
  color: H,
192
- cursor: j ? "pointer" : "default",
194
+ cursor: X ? "pointer" : "default",
193
195
  transition: "border-color 0.15s"
194
- }), V && a.addEventListener("click", () => V(p)), a.addEventListener("mouseenter", () => {
196
+ }), j && a.addEventListener("click", () => j(p)), a.addEventListener("mouseenter", () => {
195
197
  a.style.borderColor = K;
196
198
  }), a.addEventListener("mouseleave", () => {
197
199
  a.style.borderColor = E;
@@ -232,21 +234,21 @@ function _e(i, o) {
232
234
  if (t.role === "assistant" && t.status === "IN_PROGRESS") return t;
233
235
  }
234
236
  }
235
- const q = (e) => {
237
+ const V = (e) => {
236
238
  h || (h = e.conversationId);
237
- }, Y = (e) => {
239
+ }, q = (e) => {
238
240
  const t = de();
239
241
  t && (t.content += e.content, S());
240
- }, J = (e) => {
242
+ }, Y = (e) => {
241
243
  const t = n.findIndex((d) => d.id === e.id || d.role === "assistant" && d.status === "IN_PROGRESS");
242
244
  t >= 0 ? n[t] = e : n.push(e), _ = !1, S(), e.status === "DONE" && $?.({
243
245
  id: e.id,
244
246
  content: e.content
245
247
  });
246
- }, Q = (e) => {
248
+ }, J = (e) => {
247
249
  N = e.error, _ = !1, n = n.filter((t) => !t.id.startsWith("temp-")), S();
248
250
  };
249
- l.on("message:start", q), l.on("message:chunk", Y), l.on("message:complete", J), l.on("message:error", Q);
251
+ l.on("message:start", V), l.on("message:chunk", q), l.on("message:complete", Y), l.on("message:error", J);
250
252
  const ce = (B ?? []).map((e) => ue(e).install(l));
251
253
  async function F(e, t) {
252
254
  const d = e.trim();
@@ -302,13 +304,13 @@ function _e(i, o) {
302
304
  }
303
305
  return S(), ie(), h && pe(h), D && G(), {
304
306
  client: l,
305
- element: O,
307
+ element: A,
306
308
  sendMessage: F,
307
309
  session: I,
308
310
  threads: M,
309
311
  refreshThreads: G,
310
312
  destroy() {
311
- l.off("message:start", q), l.off("message:chunk", Y), l.off("message:complete", J), l.off("message:error", Q), ce.forEach((e) => e()), O.remove(), o.client || l.destroy();
313
+ l.off("message:start", V), l.off("message:chunk", q), l.off("message:complete", Y), l.off("message:error", J), ce.forEach((e) => e()), A.remove(), o.client || l.destroy();
312
314
  }
313
315
  };
314
316
  function fe() {
@@ -331,7 +333,7 @@ function _e(i, o) {
331
333
  return e;
332
334
  }
333
335
  }
334
- function we(i) {
336
+ function Re(i) {
335
337
  let o = [];
336
338
  const g = document.createElement("form");
337
339
  m(g, {
@@ -346,7 +348,7 @@ function we(i) {
346
348
  display: "flex",
347
349
  flexWrap: "wrap",
348
350
  gap: "6px"
349
- }), T = c({
351
+ }), O = c({
350
352
  display: "flex",
351
353
  gap: "8px",
352
354
  alignItems: "flex-end"
@@ -383,9 +385,9 @@ function we(i) {
383
385
  cursor: "pointer",
384
386
  fontSize: "14px"
385
387
  }), v.addEventListener("click", () => f?.click()), f.addEventListener("change", () => {
386
- o = [...o, ...Array.from(f?.files ?? [])], A();
388
+ o = [...o, ...Array.from(f?.files ?? [])], T();
387
389
  }));
388
- function A() {
390
+ function T() {
389
391
  w.replaceChildren(), o.forEach((s, C) => {
390
392
  const $ = c({
391
393
  display: "flex",
@@ -406,13 +408,13 @@ function we(i) {
406
408
  fontSize: "14px",
407
409
  lineHeight: "1"
408
410
  }), k.addEventListener("click", () => {
409
- o = o.filter((U, I) => I !== C), A();
411
+ o = o.filter((U, I) => I !== C), T();
410
412
  }), $.append(l, k), w.appendChild($);
411
413
  });
412
414
  }
413
415
  const D = () => {
414
416
  const s = u.value, C = o;
415
- return u.value = "", o = [], A(), {
417
+ return u.value = "", o = [], T(), {
416
418
  content: s,
417
419
  files: C
418
420
  };
@@ -424,7 +426,7 @@ function we(i) {
424
426
  s.preventDefault(), B();
425
427
  }), u.addEventListener("keydown", (s) => {
426
428
  s.key === "Enter" && !s.shiftKey && (s.preventDefault(), B());
427
- }), v && T.appendChild(v), T.append(u, x), f && g.appendChild(f), g.append(w, T), {
429
+ }), v && O.appendChild(v), O.append(u, x), f && g.appendChild(f), g.append(w, O), {
428
430
  inputRow: g,
429
431
  getValueAndClear: D,
430
432
  setDisabled: (s) => {
@@ -434,5 +436,5 @@ function we(i) {
434
436
  };
435
437
  }
436
438
  export {
437
- _e as mountChatWidget
439
+ Ie as mountChatWidget
438
440
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useago/sdk",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "JavaScript SDK for AGO Chat integration",
5
5
  "type": "module",
6
6
  "sideEffects": false,