@useago/sdk 0.4.5 → 0.4.6

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/react.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { n as Vn, r as Wn, t as Ge } from "./rolldown-runtime-DxmricAu.js";
2
2
  import { t as ui } from "./AgoClient-rvTz2thR.js";
3
- import { n as si, t as Xn } from "./createFormCollector-Cujr7hW4.js";
3
+ import { n as si, t as Xn } from "./createFormCollector-DON4vdJV.js";
4
4
  import { t as sf } from "./createMockClient-DwdxNwEn.js";
5
5
  import ci, { createContext as fi, useCallback as xe, useContext as Yn, useEffect as te, useId as pi, useMemo as We, useRef as Ne, useState as se, useSyncExternalStore as hi } from "react";
6
6
  import { Fragment as Qn, jsx as M, jsxs as ce } from "react/jsx-runtime";
package/dist/widget.cjs CHANGED
@@ -1 +1,5 @@
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;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ke=require("./AgoClient-D4EL6nva.cjs"),$e=require("./createFormCollector-IO6bfPQx.cjs"),Ie=require("./createConversationSession-DGcM_Z3f.cjs");var Te={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};function M(o){return o.replace(/[&<>"']/g,n=>Te[n])}function se(o){const n=o.trim();return/^(https?:|mailto:|tel:|#|\/|\.\/|\.\.\/)/i.test(n)||!/^[a-z][a-z0-9+.-]*:/i.test(n)?n:null}var pe='"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace',q="";function O(o){const n=[],r=u=>(n.push(u),`${q}${n.length-1}${q}`);let e=o;return e=e.replace(/`([^`]+)`/g,(u,a)=>r(`<code style="background:#f0f2f5;padding:2px 5px;border-radius:4px;font-size:13px;font-family:${pe}">${M(a)}</code>`)),e=e.replace(/!\[([^\]]*)\]\(([^)\s]+)\)/g,(u,a,d)=>{const i=se(d);return i?r(`<img alt="${M(a)}" src="${M(i)}" style="max-width:100%;border-radius:8px;margin:4px 0" />`):u}),e=e.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g,(u,a,d)=>{const i=se(d);return i?r(`<a href="${M(i)}" target="_blank" rel="noopener noreferrer" style="color:#1b5fc4;text-decoration:underline">${O(a)}</a>`):u}),e=M(e),e=e.replace(/\*\*([^*]+?)\*\*/g,"<strong>$1</strong>").replace(/__([^_]+?)__/g,"<strong>$1</strong>").replace(/~~([^~]+?)~~/g,"<del>$1</del>").replace(/(^|[^*])\*(?!\s)([^*]+?)\*/g,"$1<em>$2</em>").replace(/(^|[^\w_])_(?!\s)([^_]+?)_/g,"$1<em>$2</em>"),e=e.replace(new RegExp(`${q}(\\d+)${q}`,"g"),(u,a)=>n[Number(a)]),e}function y(o,n,r){const e=document.createElement(o);return Object.assign(e.style,n),r!==void 0&&(e.innerHTML=r),e}var fe=/^ {0,3}([-*_])( *\1){2,} *$/,ue=/^ {0,3}(#{1,6})\s+(.*?)\s*#*\s*$/,ge=/^ {0,3}(```+|~~~+)/,j=/^ {0,3}>\s?/,H=/^(\s*)([-*+]|\d+[.)])\s+(.*)$/,Ae=["20px","18px","16px","15px","14px","13px"],Z=o=>o.match(/^\s*/)?.[0].length??0;function Le(o){return o.trim()===""||fe.test(o)||ue.test(o)||ge.test(o)||j.test(o)||H.test(o)}function me(o){const n=o[0].match(H),r=n[1].length,e=/\d/.test(n[2]),u=y(e?"ol":"ul",{margin:"0 0 8px 0",paddingLeft:"20px",listStyleType:e?"decimal":"disc",listStylePosition:"outside"});let a=0;for(;a<o.length;){const d=o[a].match(H),i=[];for(a++;a<o.length&&Z(o[a])>r;)i.push(o[a]),a++;const c=y("li",{display:"list-item",margin:"2px 0",lineHeight:"1.6"}),l=d[3].match(/^\[([ xX])\]\s+(.*)$/);l?(c.style.listStyleType="none",c.style.marginLeft="-20px",c.innerHTML=`<span style="margin-right:6px">${l[1].toLowerCase()==="x"?"☑":"☐"}</span>${O(l[2])}`):c.innerHTML=O(d[3]),i.filter(h=>H.test(h)).length>0&&c.appendChild(me(i.filter(h=>h.trim()!==""))),u.appendChild(c)}return u}function Oe(o){const n=i=>i.replace(/^\s*\|?/,"").replace(/\|?\s*$/,"").split("|").map(c=>c.trim()),r=y("div",{overflowX:"auto",margin:"0 0 8px 0"}),e=y("table",{borderCollapse:"collapse",width:"100%",fontSize:"13px"}),u=document.createElement("thead"),a=document.createElement("tr");for(const i of n(o[0]))a.appendChild(y("th",{border:"1px solid #dee3e8",padding:"6px 10px",textAlign:"left",backgroundColor:"#f5f7fa",fontWeight:"600"},O(i)));u.appendChild(a),e.appendChild(u);const d=document.createElement("tbody");for(const i of o.slice(2)){const c=document.createElement("tr");for(const l of n(i))c.appendChild(y("td",{border:"1px solid #dee3e8",padding:"6px 10px"},O(l)));d.appendChild(c)}return e.appendChild(d),r.appendChild(e),r}var Ne=o=>!!o&&/^\s*\|?\s*:?-{1,}:?\s*(\|\s*:?-{1,}:?\s*)*\|?\s*$/.test(o);function J(o){const n=document.createDocumentFragment(),r=o.replace(/\r\n?/g,`
2
+ `).split(`
3
+ `);let e=0;for(;e<r.length;){const a=r[e];if(a.trim()===""){e++;continue}const d=a.match(ge);if(d){const l=d[1][0],h=[];for(e++;e<r.length&&!new RegExp(`^ {0,3}${l==="`"?"`{3,}":"~{3,}"}\\s*$`).test(r[e]);)h.push(r[e]),e++;e++;const T=y("pre",{margin:"0 0 8px 0"});T.appendChild(y("code",{display:"block",background:"#f5f5f5",padding:"8px 12px",borderRadius:"6px",fontSize:"13px",overflowX:"auto",fontFamily:pe,whiteSpace:"pre"},M(h.join(`
4
+ `)))),n.appendChild(T);continue}if(fe.test(a)){n.appendChild(y("hr",{border:"none",borderTop:"1px solid #dee3e8",margin:"12px 0"})),e++;continue}const i=a.match(ue);if(i){const l=i[1].length;n.appendChild(y(`h${l}`,{margin:"16px 0 8px 0",fontSize:Ae[l-1],fontWeight:"600",lineHeight:"1.3"},O(i[2]))),e++;continue}if(j.test(a)){const l=[];for(;e<r.length&&j.test(r[e]);)l.push(r[e].replace(j,"")),e++;const h=y("blockquote",{borderLeft:"4px solid #dee3e8",paddingLeft:"12px",margin:"0 0 8px 0",fontStyle:"italic",color:"#6b6d6f"});h.appendChild(J(l.join(`
5
+ `))),n.appendChild(h);continue}if(a.includes("|")&&Ne(r[e+1])){const l=[a,r[e+1]];for(e+=2;e<r.length&&r[e].includes("|")&&r[e].trim();)l.push(r[e]),e++;n.appendChild(Oe(l));continue}if(H.test(a)){const l=[],h=Z(a);for(;e<r.length&&r[e].trim()!=="";)if(H.test(r[e])||Z(r[e])>h)l.push(r[e]),e++;else break;n.appendChild(me(l));continue}const c=[a];for(e++;e<r.length&&!Le(r[e]);)c.push(r[e]),e++;n.appendChild(y("p",{margin:"0 0 8px 0",lineHeight:"1.6"},c.map(l=>O(l)).join("<br>")))}const u=n.lastElementChild;return u&&(u.style.marginBottom="0"),n}var he='var(--ago-font, "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif)',le={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"},xe="var(--ago-brand-color, #03182f)",be="var(--ago-brand-text-color, #fff)",De="var(--ago-header-background, var(--ago-brand-color, #03182f))",Me="var(--ago-header-text-color, #e8f0fe)",z="var(--ago-panel-background, #fff)",He="var(--ago-messages-background, #fbfbfb)",G="var(--ago-text-color, #30373e)",Be="var(--ago-muted-text-color, #6b6d6f)",k="var(--ago-border-color, #dee3e8)",Y="var(--ago-accent-color, #1b5fc4)",ze="var(--ago-radius, 16px)",de="var(--ago-message-radius, 16px)";function Ue(o,n){if(n)for(const r of Object.keys(le)){const e=n[r];e!=null&&o.style.setProperty(le[r],e)}}function E(o,n){Object.assign(o.style,n)}function C(o={}){const n=document.createElement("div");return E(n,o),n}var ce="ago-chat-widget-keyframes";function Fe(){if(typeof document>"u"||document.getElementById(ce))return;const o=document.createElement("style");o.id=ce,o.textContent="@keyframes ago-pulse { 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); } 40% { opacity: 1; transform: scale(1); } }",document.head.appendChild(o)}function We(o){const n=typeof o=="string"?document.querySelector(o):o;if(!n)throw new Error(`mountChatWidget: target "${String(o)}" not found.`);return n}function Pe(o,n){const{title:r="Chat",welcomeMessage:e="Hello! How can I help you today?",placeholder:u="Type a message...",allowFiles:a=!1,height:d=500,logoUrl:i,showAgentName:c=!1,theme:l,loadThreads:h=!1,forms:T,onFollowUpClick:m,onMessageSent:_,onMessageReceived:U}=n;if(!n.client&&!n.config?.baseUrl)throw new Error("mountChatWidget requires either `client` or `config` (with a baseUrl).");const x=n.client??new ke.AgoClient(n.config),A=We(o),F=n.persistConversation,N=F?Ie.createConversationSession(F===!0?{}:F):void 0;let w=n.conversationId??N?.getLastActiveThread()??void 0,p=[],L=!1,B=null;const W=[],D=C({display:"flex",flexDirection:"column",height:typeof d=="number"?`${d}px`:d,border:`1px solid ${k}`,borderRadius:ze,overflow:"hidden",backgroundColor:z,fontFamily:he,textAlign:"left",boxShadow:"rgba(15, 15, 15, 0.08) 0px 2px 16px 0px"});D.className="ago-chat-widget",Ue(D,l);const P=C({padding:"14px 16px",borderBottom:`1px solid ${k}`,backgroundColor:De,color:Me,display:"flex",alignItems:"center",gap:"10px"});if(P.className="ago-chat-widget__header",i){const t=document.createElement("img");t.src=i,t.alt="Logo",E(t,{height:"24px",width:"auto"}),P.appendChild(t)}const X=document.createElement("h3");X.textContent=r,E(X,{margin:"0",fontSize:"15px",fontWeight:"600"}),P.appendChild(X);const $=C({flex:"1",overflow:"auto",padding:"16px",backgroundColor:He});$.className="ago-chat-widget__messages";const{inputRow:Ce,setDisabled:ve,focus:ye}=qe({placeholder:u,allowFiles:a,onSend:(t,s)=>{K(t,s)}});Fe(),D.append(P,$,Ce),A.appendChild(D);const ee=m!==!1,te=m===!1?void 0:m??(t=>{K(t)});function Ee(t){const s=t.role==="user",b=C({display:"flex",flexDirection:"column",alignItems:s?"flex-end":"flex-start",marginBottom:"16px"});if(b.className=`ago-message ago-message--${t.role}`,!s&&c&&t.agent){const f=C({fontSize:"13px",fontWeight:"500",color:G,marginBottom:"6px",padding:"0 4px"});f.className="ago-message__agent",f.textContent=t.agent.displayName||t.agent.name,b.appendChild(f)}if(!s&&t.sources&&t.sources.length>0){const f=C({display:"grid",gridTemplateColumns:"1fr 1fr",gap:"6px",marginBottom:"10px",width:"100%",maxWidth:"85%"});f.className="ago-message__sources",t.sources.forEach((v,g)=>{const R=v.url?document.createElement("a"):document.createElement("div");v.url&&R instanceof HTMLAnchorElement&&(R.href=v.url,R.target="_blank",R.rel="noopener noreferrer"),E(R,{display:"flex",alignItems:"center",gap:"8px",padding:"8px 10px",border:`1px solid ${k}`,borderRadius:"8px",backgroundColor:z,textDecoration:"none",color:G,fontSize:"12px",overflow:"hidden"});const ie=C({flexShrink:"0",width:"18px",height:"18px",borderRadius:"3px",border:`1px solid ${Y}`,color:Y,fontSize:"11px",fontWeight:"500",display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"#f0f4ff"});ie.textContent=String(g+1);const Q=C({overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});Q.textContent=v.title,Q.title=v.title,R.append(ie,Q),f.appendChild(R)}),b.appendChild(f)}const S=C({maxWidth:s?"75%":"100%",padding:s?"10px 14px":"2px 8px",borderRadius:s?de:"0",backgroundColor:s?xe:"transparent",color:s?be:G,wordBreak:"break-word",fontSize:"14px",lineHeight:"1.6"});if(S.className="ago-message__content",t.content?S.appendChild(J(t.content)):t.status==="IN_PROGRESS"&&S.appendChild(Re()),b.appendChild(S),t.followUpReplies&&t.followUpReplies.length>0){const f=C({display:"flex",flexWrap:"wrap",gap:"8px",marginTop:"10px"});f.className="ago-message__followups";for(const v of t.followUpReplies){const g=document.createElement("button");g.type="button",g.className="ago-message__followup-btn",g.textContent=v,g.disabled=!ee,E(g,{padding:"6px 14px",fontSize:"13px",borderRadius:de,border:`1px solid ${k}`,backgroundColor:z,color:G,cursor:ee?"pointer":"default",transition:"border-color 0.15s"}),te&&g.addEventListener("click",()=>te(v)),g.addEventListener("mouseenter",()=>{g.style.borderColor=Y}),g.addEventListener("mouseleave",()=>{g.style.borderColor=k}),f.appendChild(g)}b.appendChild(f)}return b}function I(){if($.replaceChildren(),p.length===0){const t=C({textAlign:"center",color:Be,padding:"24px 16px",fontSize:"14px",lineHeight:"1.5"});t.textContent=e,$.appendChild(t)}else for(const t of p)$.appendChild(Ee(t));if(B){const t=C({padding:"10px 14px",backgroundColor:"#fef2f2",color:"#dc2626",borderRadius:"12px",marginTop:"8px",fontSize:"13px",border:"1px solid #fecaca"});t.textContent=B,$.appendChild(t)}$.scrollTop=$.scrollHeight,ve(L)}function we(){for(let t=p.length-1;t>=0;t--){const s=p[t];if(s.role==="assistant"&&s.status==="IN_PROGRESS")return s}}const ne=t=>{w||(w=t.conversationId)},oe=t=>{const s=we();s&&(s.content+=t.content,I())},re=t=>{const s=p.findIndex(b=>b.id===t.id||b.role==="assistant"&&b.status==="IN_PROGRESS");s>=0?p[s]=t:p.push(t),L=!1,I(),t.status==="DONE"&&U?.({id:t.id,content:t.content})},ae=t=>{B=t.error,L=!1,p=p.filter(s=>!s.id.startsWith("temp-")),I()};x.on("message:start",ne),x.on("message:chunk",oe),x.on("message:complete",re),x.on("message:error",ae);const Se=(T??[]).map(t=>$e.createFormCollector(t).install(x));async function K(t,s){const b=t.trim();if(!b&&!s?.length||L)return;_?.(b),L=!0,B=null;const S=Date.now();p.push({id:`temp-user-${S}`,conversationId:w||"",content:b,role:"user",status:"DONE",createdAt:new Date}),p.push({id:`temp-assistant-${S}`,conversationId:w||"",content:"",role:"assistant",status:"IN_PROGRESS",createdAt:new Date}),I();try{const f=await x.sendMessage(b,{conversationId:w,files:s});f.conversationId&&(w||(w=f.conversationId),N?.setActiveThread(f.conversationId,f.createdAt));const v=p.find(g=>g.id===`temp-user-${S}`);if(v&&(v.id=`user-${S}`,v.conversationId=f.conversationId),!p.some(g=>g.id===f.id)){const g=p.findIndex(R=>R.id===`temp-assistant-${S}`);g>=0?p[g]=f:p.push(f)}p=p.filter(g=>!g.id.startsWith("temp-")),L=!1,I(),h&&V()}catch(f){B=f instanceof Error?f.message:"Failed to send message",L=!1,p=p.filter(v=>!v.id.startsWith("temp-")),I()}}async function V(){try{const t=await x.getConversations();W.splice(0,W.length,...t)}catch{}return W}async function _e(t){try{const s=(await x.getConversation(t))?.messages??[];s.length>0&&p.length===0&&(p=s,I())}catch{p.length===0&&(N?.clear(),w=void 0)}}return I(),ye(),w&&_e(w),h&&V(),{client:x,element:D,sendMessage:K,session:N,threads:W,refreshThreads:V,destroy(){x.off("message:start",ne),x.off("message:chunk",oe),x.off("message:complete",re),x.off("message:error",ae),Se.forEach(t=>t()),D.remove(),n.client||x.destroy()}};function Re(){const t=C({display:"flex",gap:"4px",padding:"4px 0"});for(let s=0;s<3;s++){const b=C({width:"6px",height:"6px",borderRadius:"50%",backgroundColor:"#b5bfc8",animation:"ago-pulse 1.2s ease-in-out infinite",animationDelay:`${s*.2}s`});t.appendChild(b)}return t}}function qe(o){let n=[];const r=document.createElement("form");E(r,{display:"flex",flexDirection:"column",gap:"8px",padding:"12px",borderTop:`1px solid ${k}`,backgroundColor:z}),r.className="ago-chat-input";const e=C({display:"flex",flexWrap:"wrap",gap:"6px"}),u=C({display:"flex",gap:"8px",alignItems:"flex-end"}),a=document.createElement("textarea");a.placeholder=o.placeholder,a.rows=1,E(a,{flex:"1",resize:"none",padding:"10px 12px",border:`1px solid ${k}`,borderRadius:"12px",fontSize:"14px",fontFamily:he,lineHeight:"1.4",maxHeight:"120px",outline:"none"});const d=document.createElement("button");d.type="submit",d.textContent="Send",E(d,{padding:"10px 16px",border:"none",borderRadius:"12px",backgroundColor:xe,color:be,fontSize:"14px",fontWeight:"500",cursor:"pointer"});let i=null,c=null;o.allowFiles&&(i=document.createElement("input"),i.type="file",i.multiple=!0,E(i,{display:"none"}),c=document.createElement("button"),c.type="button",c.textContent="📎",E(c,{padding:"10px 12px",border:`1px solid ${k}`,borderRadius:"12px",backgroundColor:z,cursor:"pointer",fontSize:"14px"}),c.addEventListener("click",()=>i?.click()),i.addEventListener("change",()=>{n=[...n,...Array.from(i?.files??[])],l()}));function l(){e.replaceChildren(),n.forEach((m,_)=>{const U=C({display:"flex",alignItems:"center",gap:"4px",padding:"4px 8px",backgroundColor:"#f0f4ff",border:`1px solid ${k}`,borderRadius:"8px",fontSize:"12px"}),x=document.createElement("span");x.textContent=m.name;const A=document.createElement("button");A.type="button",A.textContent="×",E(A,{border:"none",background:"transparent",cursor:"pointer",fontSize:"14px",lineHeight:"1"}),A.addEventListener("click",()=>{n=n.filter((F,N)=>N!==_),l()}),U.append(x,A),e.appendChild(U)})}const h=()=>{const m=a.value,_=n;return a.value="",n=[],l(),{content:m,files:_}},T=()=>{const{content:m,files:_}=h();(m.trim()||_.length>0)&&o.onSend(m.trim(),_.length>0?_:void 0)};return r.addEventListener("submit",m=>{m.preventDefault(),T()}),a.addEventListener("keydown",m=>{m.key==="Enter"&&!m.shiftKey&&(m.preventDefault(),T())}),c&&u.appendChild(c),u.append(a,d),i&&r.appendChild(i),r.append(e,u),{inputRow:r,getValueAndClear:h,setDisabled:m=>{a.disabled=m,d.disabled=m,d.style.opacity=m?"0.6":"1",d.style.cursor=m?"not-allowed":"pointer"},focus:()=>a.focus()}}exports.mountChatWidget=Pe;exports.renderMarkdown=J;
package/dist/widget.d.cts CHANGED
@@ -586,8 +586,9 @@ declare type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCEL
586
586
  * Vue, or Angular required. Mirrors the React `<ChatWidget>`: it streams replies,
587
587
  * renders clickable suggested replies, and installs conversational form collectors.
588
588
  *
589
- * Message content is rendered as plain text (no markdown) to stay dependency-free;
590
- * use the React `<Message>` component if you need GitHub-flavored markdown.
589
+ * Message content is rendered as GitHub-flavored markdown by a tiny built-in
590
+ * parser (no dependencies); all message text is HTML-escaped first (see
591
+ * {@link renderMarkdown}).
591
592
  *
592
593
  * ```ts
593
594
  * import { mountChatWidget } from "@useago/sdk/widget";
@@ -678,6 +679,34 @@ export declare interface MountChatWidgetOptions {
678
679
  }) => void;
679
680
  }
680
681
 
682
+ /**
683
+ * Tiny, dependency-free markdown → DOM renderer for the vanilla chat widget.
684
+ *
685
+ * The React widget renders GitHub-flavored markdown via `react-markdown` +
686
+ * `remark-gfm`; bundling those into the framework-agnostic widget would defeat
687
+ * its "no dependencies" promise, so this is a hand-rolled subset that mirrors
688
+ * the visible styling of `react/components/Markdown.tsx`.
689
+ *
690
+ * Supported: paragraphs (single newline → `<br>`), ATX headings, **bold**,
691
+ * *italic*, ~~strikethrough~~, `inline code`, fenced code blocks, links,
692
+ * images, ordered/unordered (and nested) lists, blockquotes, horizontal rules,
693
+ * and GFM tables.
694
+ *
695
+ * ## Security
696
+ *
697
+ * The widget is embedded into third-party pages, so the agent's message content
698
+ * is untrusted. Every span of message text is HTML-escaped before it reaches the
699
+ * DOM; only a fixed set of safe tags is ever emitted, and `href`/`src` URLs are
700
+ * scheme-validated (see {@link safeUrl}) so `javascript:`/`data:` payloads can't
701
+ * slip through. Callers should append the returned fragment — never feed raw
702
+ * message content to `innerHTML` directly.
703
+ */
704
+ /**
705
+ * Parse a markdown string into a {@link DocumentFragment} of safely-built block
706
+ * elements. Append it to the message bubble; do not stringify it back to HTML.
707
+ */
708
+ export declare function renderMarkdown(source: string): DocumentFragment;
709
+
681
710
  /**
682
711
  * Options for sending a message
683
712
  */
package/dist/widget.d.ts CHANGED
@@ -586,8 +586,9 @@ declare type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCEL
586
586
  * Vue, or Angular required. Mirrors the React `<ChatWidget>`: it streams replies,
587
587
  * renders clickable suggested replies, and installs conversational form collectors.
588
588
  *
589
- * Message content is rendered as plain text (no markdown) to stay dependency-free;
590
- * use the React `<Message>` component if you need GitHub-flavored markdown.
589
+ * Message content is rendered as GitHub-flavored markdown by a tiny built-in
590
+ * parser (no dependencies); all message text is HTML-escaped first (see
591
+ * {@link renderMarkdown}).
591
592
  *
592
593
  * ```ts
593
594
  * import { mountChatWidget } from "@useago/sdk/widget";
@@ -678,6 +679,34 @@ export declare interface MountChatWidgetOptions {
678
679
  }) => void;
679
680
  }
680
681
 
682
+ /**
683
+ * Tiny, dependency-free markdown → DOM renderer for the vanilla chat widget.
684
+ *
685
+ * The React widget renders GitHub-flavored markdown via `react-markdown` +
686
+ * `remark-gfm`; bundling those into the framework-agnostic widget would defeat
687
+ * its "no dependencies" promise, so this is a hand-rolled subset that mirrors
688
+ * the visible styling of `react/components/Markdown.tsx`.
689
+ *
690
+ * Supported: paragraphs (single newline → `<br>`), ATX headings, **bold**,
691
+ * *italic*, ~~strikethrough~~, `inline code`, fenced code blocks, links,
692
+ * images, ordered/unordered (and nested) lists, blockquotes, horizontal rules,
693
+ * and GFM tables.
694
+ *
695
+ * ## Security
696
+ *
697
+ * The widget is embedded into third-party pages, so the agent's message content
698
+ * is untrusted. Every span of message text is HTML-escaped before it reaches the
699
+ * DOM; only a fixed set of safe tags is ever emitted, and `href`/`src` URLs are
700
+ * scheme-validated (see {@link safeUrl}) so `javascript:`/`data:` payloads can't
701
+ * slip through. Callers should append the returned fragment — never feed raw
702
+ * message content to `innerHTML` directly.
703
+ */
704
+ /**
705
+ * Parse a markdown string into a {@link DocumentFragment} of safely-built block
706
+ * elements. Append it to the message bubble; do not stringify it back to HTML.
707
+ */
708
+ export declare function renderMarkdown(source: string): DocumentFragment;
709
+
681
710
  /**
682
711
  * Options for sending a message
683
712
  */