@useago/sdk 1.4.2 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +4 -1
  2. package/dist/AgoClient-CLmtYTJx.cjs +8 -0
  3. package/dist/{AgoClient-BdtuHX7k.js → AgoClient-Ozz2b1dQ.js} +301 -161
  4. package/dist/angular.cjs +1 -1
  5. package/dist/angular.d.cts +151 -6
  6. package/dist/angular.d.ts +151 -6
  7. package/dist/angular.js +1 -1
  8. package/dist/{createConversationSession-B8zfTL78.cjs → createConversationSession-CUkNp6mZ.cjs} +1 -1
  9. package/dist/{createConversationSession-CWpf4u6I.js → createConversationSession-QIBN0gLx.js} +1 -1
  10. package/dist/{createFormCollector-BB_l0Sia.cjs → createFormCollector-DHT1ObOb.cjs} +1 -1
  11. package/dist/{createFormCollector-B4n0_diV.js → createFormCollector-F3YJfsbg.js} +1 -1
  12. package/dist/createMockClient-BSr-UV8R.cjs +1 -0
  13. package/dist/{createMockClient-d-arlmCq.js → createMockClient-bAZ9KBHC.js} +18 -15
  14. package/dist/devtools.d.cts +149 -4
  15. package/dist/devtools.d.ts +149 -4
  16. package/dist/helpers.d.cts +6 -0
  17. package/dist/helpers.d.ts +6 -0
  18. package/dist/index.cjs +1 -1
  19. package/dist/index.d.cts +181 -5
  20. package/dist/index.d.ts +181 -5
  21. package/dist/index.js +4 -4
  22. package/dist/react.cjs +3 -3
  23. package/dist/react.d.cts +169 -10
  24. package/dist/react.d.ts +169 -10
  25. package/dist/react.js +441 -428
  26. package/dist/testing.cjs +1 -1
  27. package/dist/testing.d.cts +149 -4
  28. package/dist/testing.d.ts +149 -4
  29. package/dist/testing.js +1 -1
  30. package/dist/vue.cjs +1 -1
  31. package/dist/vue.d.cts +162 -5
  32. package/dist/vue.d.ts +162 -5
  33. package/dist/vue.js +22 -21
  34. package/dist/widget.cjs +3 -3
  35. package/dist/widget.d.cts +149 -4
  36. package/dist/widget.d.ts +149 -4
  37. package/dist/widget.js +120 -120
  38. package/llms-full.txt +1910 -0
  39. package/package.json +5 -3
  40. package/dist/AgoClient-CRAnT4qE.cjs +0 -8
  41. package/dist/createMockClient-ucPENDzz.cjs +0 -1
package/dist/react.cjs CHANGED
@@ -1,7 +1,7 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("./rolldown-runtime-16Nf8qvH.cjs"),R=require("./AgoClient-CRAnT4qE.cjs"),M=require("./createFormCollector-BB_l0Sia.cjs"),V=require("./createMockClient-ucPENDzz.cjs");let s=require("react");s=T.__toESM(s,1);let o=require("react/jsx-runtime"),_=require("react-markdown");_=T.__toESM(_,1);let N=require("remark-gfm");N=T.__toESM(N,1);function O(e){const[t,r]=(0,s.useState)(!1),n=(0,s.useRef)(null),a=(0,s.useMemo)(()=>{if(n.current&&(n.current.destroy(),n.current=null),!e)return null;const l=new R.AgoClient(e);return n.current=l,l},[e?.baseUrl,e?.widgetId]);return(0,s.useEffect)(()=>(r(!0),()=>{n.current?.destroy(),n.current=null}),[a]),(0,s.useEffect)(()=>{n.current&&e&&n.current.updateConfig({agent:e.agent,defaultAgentId:e.defaultAgentId,permission:e.permission,userEmail:e.userEmail,userJwt:e.userJwt,debug:e.debug,warnOnEmptyReply:e.warnOnEmptyReply})},[e?.agent,e?.defaultAgentId,e?.permission,e?.userEmail,e?.userJwt,e?.debug,e?.warnOnEmptyReply]),{client:a,isReady:t}}var D=(0,s.createContext)(null),Y=({children:e,client:t,tools:r,helpers:n,pageContext:a,...l})=>{const{client:d}=O(t?null:l),c=t||d;return(0,s.useEffect)(()=>{if(!(!r||r.length===0)){for(const p of r)c.register(p);return()=>{for(const p of r)c.unregisterFunction(p.name)}}},[c,r]),(0,s.useEffect)(()=>{if(!n)return;const p=[];return Promise.resolve().then(()=>require("./functions-Djnq-JAo.cjs")).then(f=>f.functions_exports).then(f=>{for(const[v,x]of Object.entries(n)){const y=f[v];if(!y){console.warn(`[AGO] Unknown helper: "${v}"`);continue}const h=x===!0?y:{...y,handler:x};c.register(h),p.push(h.name)}}),()=>{for(const f of p)c.unregisterFunction(f)}},[c,n]),(0,s.useEffect)(()=>{a==="auto"&&c.enableAutoPageContext()},[c,a]),(0,o.jsx)(D.Provider,{value:c,children:e})};function I(){const e=(0,s.useContext)(D);if(!e)throw new Error('useAgoClient must be used within an <AgoProvider>. Wrap your component tree with <AgoProvider baseUrl="...">.');return e}function F(){return(0,s.useContext)(D)}function z({client:e,conversationId:t}={}){const r=F(),n=e||r;if(!n)throw new Error("useMessages requires an AgoClient. Either pass it as options.client or wrap your app in <AgoProvider>.");const[a,l]=(0,s.useState)([]),[d,c]=(0,s.useState)(t),[p,f]=(0,s.useState)(!1),[v,x]=(0,s.useState)(null);(0,s.useEffect)(()=>{t&&t!==d&&(c(t),y(t))},[t]);const y=async h=>{try{l((await n.getMessages(h)).filter(m=>!m.hidden))}catch(m){x(m instanceof Error?m:new Error("Failed to load messages"))}};return(0,s.useEffect)(()=>{const h=g=>{d||c(g.conversationId),f(!0),l(u=>u.some(b=>b.role==="assistant"&&b.status==="IN_PROGRESS")?u:[...u,{id:g.messageId,conversationId:g.conversationId,content:"",role:"assistant",status:"IN_PROGRESS",createdAt:new Date}])},m=g=>{l(u=>{const b=u[u.length-1];return b&&b.id===g.messageId?[...u.slice(0,-1),{...b,content:b.content+g.content}]:u})},C=g=>{l(u=>{let b=-1;for(let k=u.length-1;k>=0;k--)if(u[k].role==="assistant"&&u[k].status==="IN_PROGRESS"){b=k;break}return b<0?u:[...u.slice(0,b),{...u[b],...g},...u.slice(b+1)]})},w=g=>{l(u=>{const b=u.findIndex(k=>k.id===g.id);return b>=0?[...u.slice(0,b),g,...u.slice(b+1)]:[...u,g]}),f(!1)},i=g=>{x(new Error(g.error)),f(!1)};return n.on("message:start",h),n.on("message:chunk",m),n.on("message:answer-complete",C),n.on("message:complete",w),n.on("message:error",i),()=>{n.off("message:start",h),n.off("message:chunk",m),n.off("message:answer-complete",C),n.off("message:complete",w),n.off("message:error",i)}},[n,d]),{messages:a,isLoading:p,error:v,sendMessage:(0,s.useCallback)(async(h,m)=>{f(!0),x(null);const C={id:`temp-${Date.now()}`,conversationId:d||"",content:h,role:"user",status:"DONE",attachments:m&&m.length>0?R.attachmentsFromFiles(m):void 0,createdAt:new Date},w={id:`temp-assistant-${Date.now()}`,conversationId:d||"",content:"",role:"assistant",status:"IN_PROGRESS",createdAt:new Date};l(i=>[...i,C,w]);try{const i=await n.sendMessage(h,{conversationId:d,files:m});return i.conversationId&&!d&&c(i.conversationId),l(g=>{const u=g.filter(k=>!k.id.startsWith("temp-")),b={...C,id:C.id.replace("temp-","user-"),conversationId:i.conversationId};return u.some(k=>k.id===i.id)?[...u,b].sort((k,P)=>new Date(k.createdAt).getTime()-new Date(P.createdAt).getTime()):[...u,b,i]}),i}catch(i){return x(i instanceof Error?i:new Error("Failed to send message")),f(!1),l(g=>g.filter(u=>!u.id.startsWith("temp-"))),null}},[n,d]),clearMessages:(0,s.useCallback)(()=>{l([]),c(void 0),x(null)},[]),conversationId:d}}var H=({onSend:e,disabled:t=!1,placeholder:r="Type a message...",allowFiles:n=!1,className:a=""})=>{const[l,d]=(0,s.useState)(""),[c,p]=(0,s.useState)([]),f=(0,s.useRef)(null),v=(0,s.useRef)(null),x=(0,s.useCallback)(()=>{const i=v.current;if(!i)return;const g=110;i.style.height="auto",i.style.height=`${Math.min(i.scrollHeight+2,g)}px`,i.style.overflowY=i.scrollHeight+2>g?"auto":"hidden"},[]),y=(0,s.useCallback)(i=>{i.preventDefault(),(l.trim()||c.length>0)&&(e(l.trim(),c.length>0?c:void 0),d(""),p([]),requestAnimationFrame(x))},[l,c,e,x]),h=(0,s.useCallback)(i=>{i.key==="Enter"&&!i.shiftKey&&(i.preventDefault(),y(i))},[y]),m=(0,s.useCallback)(i=>{const g=Array.from(i.target.files||[]);p(u=>[...u,...g])},[]),C=(0,s.useCallback)(i=>{p(g=>g.filter((u,b)=>b!==i))},[]),w=l.trim()||c.length>0;return(0,o.jsxs)("form",{onSubmit:y,className:`ago-chat-input ${a}`,style:{display:"flex",flexDirection:"column",gap:"8px",padding:"12px 16px",borderTop:"1px solid #dee3e8",backgroundColor:"#fff"},children:[c.length>0&&(0,o.jsx)("div",{className:"ago-chat-input__files",style:{display:"flex",flexWrap:"wrap",gap:"6px"},children:c.map((i,g)=>(0,o.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"6px",padding:"4px 10px",backgroundColor:"#f0f2f5",borderRadius:"6px",fontSize:"12px",color:"#30373e"},children:[(0,o.jsx)("span",{style:{maxWidth:"120px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:i.name}),(0,o.jsx)("button",{type:"button",onClick:()=>C(g),"aria-label":`Remove ${i.name}`,style:{border:"none",background:"none",cursor:"pointer",padding:"0",color:"#6b6d6f",fontSize:"14px",lineHeight:1},children:"×"})]},g))}),(0,o.jsxs)("div",{style:{display:"flex",gap:"8px",alignItems:"flex-end"},children:[n&&(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("button",{type:"button",onClick:()=>f.current?.click(),disabled:t,"aria-label":"Attach file",style:{padding:"8px",border:"1px solid #dee3e8",borderRadius:"8px",backgroundColor:"#fff",cursor:t?"not-allowed":"pointer",color:"#6b6d6f",fontSize:"16px",lineHeight:1},children:"+"}),(0,o.jsx)("input",{ref:f,type:"file",multiple:!0,onChange:m,style:{display:"none"}})]}),(0,o.jsx)("textarea",{ref:v,value:l,onChange:i=>{d(i.target.value),x()},onKeyDown:h,placeholder:r,"aria-label":r,disabled:t,rows:1,style:{flex:1,padding:"10px 14px",border:"1px solid #dee3e8",borderRadius:"20px",resize:"none",outline:"none",boxSizing:"border-box",maxHeight:"110px",overflowY:"hidden",fontFamily:"inherit",fontSize:"16px",lineHeight:1.4,color:"#30373e",backgroundColor:"#f8f8f8",transition:"border-color 0.15s"},onFocus:i=>{i.currentTarget.style.borderColor="#1b5fc4"},onBlur:i=>{i.currentTarget.style.borderColor="#dee3e8"}}),(0,o.jsx)("button",{type:"submit",disabled:t||!w,style:{padding:"10px 18px",border:"none",borderRadius:"20px",backgroundColor:t||!w?"#b5bfc8":"#03182f",color:"#fff",cursor:t||!w?"not-allowed":"pointer",fontWeight:500,fontSize:"16px",transition:"background-color 0.15s"},children:"Send"})]})]})},X=({href:e,children:t,...r})=>(0,o.jsx)("a",{href:e,target:"_blank",rel:"noopener noreferrer",style:{color:"#1b5fc4",textDecoration:"underline"},...r,children:t}),Q=({children:e,...t})=>(0,o.jsx)("p",{style:{margin:"0 0 8px 0",lineHeight:"1.6"},...t,children:e}),A=(e,t)=>{const r=({children:n,...a})=>s.default.createElement(`h${e}`,{style:{margin:"16px 0 8px 0",fontSize:t,fontWeight:600,lineHeight:"1.3"},...a},n);return r.displayName=`MarkdownHeading${e}`,r},Z=({children:e,...t})=>(0,o.jsx)("ul",{style:{margin:"0 0 8px 0",paddingLeft:"20px",listStyleType:"disc",listStylePosition:"outside"},...t,children:e}),ee=({children:e,...t})=>(0,o.jsx)("ol",{style:{margin:"0 0 8px 0",paddingLeft:"20px",listStyleType:"decimal",listStylePosition:"outside"},...t,children:e}),te=({children:e,...t})=>(0,o.jsx)("li",{style:{display:"list-item",margin:"2px 0",lineHeight:"1.6"},...t,children:e}),ne=({className:e,children:t,...r})=>e!==void 0||String(t).includes(`
2
- `)?(0,o.jsx)("code",{style:{display:"block",background:"#f5f5f5",padding:"8px 12px",borderRadius:"6px",fontSize:"13px",overflowX:"auto",fontFamily:'"IBM Plex Mono", monospace'},...r,children:t}):(0,o.jsx)("code",{style:{background:"#f0f2f5",padding:"2px 5px",borderRadius:"4px",fontSize:"13px",fontFamily:'"IBM Plex Mono", monospace'},...r,children:t}),re=({children:e,...t})=>(0,o.jsx)("pre",{style:{margin:"0 0 8px 0"},...t,children:e}),oe=({children:e,...t})=>(0,o.jsx)("blockquote",{style:{borderLeft:"4px solid #dee3e8",paddingLeft:"12px",margin:"0 0 8px 0",fontStyle:"italic",color:"#6b6d6f"},...t,children:e}),se=({children:e,...t})=>(0,o.jsx)("div",{style:{overflowX:"auto",margin:"0 0 8px 0"},children:(0,o.jsx)("table",{style:{borderCollapse:"collapse",width:"100%",fontSize:"13px"},...t,children:e})}),ae=({children:e,...t})=>(0,o.jsx)("th",{style:{border:"1px solid #dee3e8",padding:"6px 10px",textAlign:"left",backgroundColor:"#f5f7fa",fontWeight:600},...t,children:e}),ie=({children:e,...t})=>(0,o.jsx)("td",{style:{border:"1px solid #dee3e8",padding:"6px 10px"},...t,children:e}),le=({alt:e,...t})=>(0,o.jsx)("img",{alt:e??"",style:{maxWidth:"100%",borderRadius:"8px",margin:"4px 0"},...t}),ce=e=>(0,o.jsx)("hr",{style:{border:"none",borderTop:"1px solid #dee3e8",margin:"12px 0"},...e}),de={a:X,p:Q,h1:A(1,"20px"),h2:A(2,"18px"),h3:A(3,"16px"),h4:A(4,"15px"),h5:A(5,"14px"),h6:A(6,"13px"),ul:Z,ol:ee,li:te,code:ne,pre:re,blockquote:oe,table:se,th:ae,td:ie,img:le,hr:ce},ue=[N.default],q=({content:e})=>(0,o.jsx)(_.default,{remarkPlugins:ue,components:de,children:e}),fe=({attachment:e,isUser:t})=>{const r=R.safeAttachmentUrl(e.url);if(R.canInlineImage(e))return(0,o.jsx)("a",{href:r,target:"_blank",rel:"noopener noreferrer",style:{display:"inline-block",textDecoration:"none"},children:(0,o.jsx)("img",{src:r,alt:e.name,loading:"lazy",style:{maxWidth:"180px",maxHeight:"160px",objectFit:"cover",borderRadius:"10px",border:"1px solid #dee3e8",display:"block"}})});const n=R.formatFileSize(e.fileSize),a=(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("span",{style:{fontSize:"16px",lineHeight:1,flexShrink:0},"aria-hidden":!0,children:"📄"}),(0,o.jsxs)("span",{style:{display:"flex",flexDirection:"column",minWidth:0},children:[(0,o.jsx)("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",maxWidth:"160px"},title:e.name,children:e.name}),n&&(0,o.jsx)("span",{style:{fontSize:"11px",color:"#6b6d6f"},children:n})]})]}),l={display:"inline-flex",alignItems:"center",gap:"8px",padding:"8px 12px",borderRadius:"10px",border:"1px solid #dee3e8",backgroundColor:t?"rgba(255,255,255,0.12)":"#fff",color:t?"#fff":"#30373e",fontSize:"13px",textDecoration:"none",maxWidth:"220px"};return r?(0,o.jsx)("a",{href:r,target:"_blank",rel:"noopener noreferrer",style:l,children:a}):(0,o.jsx)("div",{style:l,children:a})},ge=({source:e,index:t})=>{const r=(0,o.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px",width:"100%",minWidth:0},children:[(0,o.jsx)("div",{style:{flexShrink:0,width:"18px",height:"18px",borderRadius:"3px",border:"1px solid #1b5fc4",color:"#1b5fc4",fontSize:"11px",fontWeight:500,display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"#f0f4ff"},children:t+1}),(0,o.jsx)("div",{style:{fontSize:"12px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"#30373e"},title:e.title,children:e.title})]}),n={display:"flex",alignItems:"center",padding:"8px 10px",border:"1px solid #dee3e8",borderRadius:"8px",backgroundColor:"#fff",cursor:e.url?"pointer":"default",textDecoration:"none",color:"inherit",minWidth:0,transition:"border-color 0.15s"};return e.url?(0,o.jsx)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",style:n,onMouseEnter:a=>{a.currentTarget.style.borderColor="#1b5fc4"},onMouseLeave:a=>{a.currentTarget.style.borderColor="#dee3e8"},children:r}):(0,o.jsx)("div",{style:n,children:r})},pe=()=>(0,o.jsxs)("div",{style:{display:"flex",gap:"4px",padding:"4px 0"},children:[[0,1,2].map(e=>(0,o.jsx)("div",{style:{width:"6px",height:"6px",borderRadius:"50%",backgroundColor:"#b5bfc8",animation:"ago-pulse 1.2s ease-in-out infinite",animationDelay:`${e*.2}s`}},e)),(0,o.jsx)("style",{children:`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const W=require("./rolldown-runtime-16Nf8qvH.cjs"),F=require("./AgoClient-CLmtYTJx.cjs"),M=require("./createFormCollector-DHT1ObOb.cjs"),V=require("./createMockClient-BSr-UV8R.cjs");let s=require("react");s=W.__toESM(s,1);let o=require("react/jsx-runtime"),P=require("react-markdown");P=W.__toESM(P,1);let T=require("remark-gfm");T=W.__toESM(T,1);function H(e){const[n,r]=(0,s.useState)(!1),t=(0,s.useRef)(null),a=(0,s.useMemo)(()=>{if(t.current&&(t.current.destroy(),t.current=null),!e)return null;const l=new F.AgoClient(e);return t.current=l,l},[e?.baseUrl,e?.widgetId]);return(0,s.useEffect)(()=>(r(!0),()=>{t.current?.destroy(),t.current=null}),[a]),(0,s.useEffect)(()=>{t.current&&e&&t.current.updateConfig({agent:e.agent,defaultAgentId:e.defaultAgentId,permission:e.permission,userEmail:e.userEmail,userJwt:e.userJwt,debug:e.debug,warnOnEmptyReply:e.warnOnEmptyReply})},[e?.agent,e?.defaultAgentId,e?.permission,e?.userEmail,e?.userJwt,e?.debug,e?.warnOnEmptyReply]),{client:a,isReady:n}}var D=(0,s.createContext)(null),Y=({children:e,client:n,tools:r,helpers:t,pageContext:a,...l})=>{const{client:d}=H(n?null:l),c=n||d;return(0,s.useEffect)(()=>{if(!(!r||r.length===0)){for(const p of r)c.register(p);return()=>{for(const p of r)c.unregisterFunction(p.name)}}},[c,r]),(0,s.useEffect)(()=>{if(!t)return;const p=[];return Promise.resolve().then(()=>require("./functions-Djnq-JAo.cjs")).then(u=>u.functions_exports).then(u=>{for(const[b,v]of Object.entries(t)){const I=u[b];if(!I){console.warn(`[AGO] Unknown helper: "${b}"`);continue}const g=v===!0?I:{...I,handler:v};c.register(g),p.push(g.name)}}),()=>{for(const u of p)c.unregisterFunction(u)}},[c,t]),(0,s.useEffect)(()=>{a==="auto"&&c.enableAutoPageContext()},[c,a]),(0,o.jsx)(D.Provider,{value:c,children:e})};function E(){const e=(0,s.useContext)(D);if(!e)throw new Error('useAgoClient must be used within an <AgoProvider>. Wrap your component tree with <AgoProvider baseUrl="...">.');return e}function _(){return(0,s.useContext)(D)}function L({client:e,conversationId:n}={}){const r=_(),t=e||r;if(!t)throw new Error("useMessages requires an AgoClient. Either pass it as options.client or wrap your app in <AgoProvider>.");const[a,l]=(0,s.useState)([]),[d,c]=(0,s.useState)(n),[p,u]=(0,s.useState)(!1),[b,v]=(0,s.useState)(null);(0,s.useEffect)(()=>{n&&n!==d&&(c(n),I(n))},[n]);const I=async g=>{try{l((await t.getMessages(g)).filter(m=>!m.hidden))}catch(m){v(m instanceof Error?m:new Error("Failed to load messages"))}};return(0,s.useEffect)(()=>{const g=f=>f==="IN_PROGRESS"||f==="WAITING_CLIENT",m=f=>{d||c(f.conversationId),u(!0),l(x=>{const C=x.findIndex(h=>h.id===f.messageId);return C>=0?x.map((h,N)=>N===C?{...h,status:"IN_PROGRESS"}:h):x.some(h=>h.role==="assistant"&&g(h.status))?x:[...x,{id:f.messageId,conversationId:f.conversationId,content:"",role:"assistant",status:"IN_PROGRESS",createdAt:new Date}]})},S=f=>{l(x=>{const C=x.findIndex(h=>h.id===f.messageId);return C<0?x:x.map((h,N)=>N===C?{...h,content:h.content+f.content}:h)})},w=f=>{l(x=>{let C=-1;for(let h=x.length-1;h>=0;h--)if(x[h].role==="assistant"&&g(x[h].status)){C=h;break}return C<0?x:[...x.slice(0,C),{...x[C],...f},...x.slice(C+1)]})},i=f=>{l(x=>{const C=x.findIndex(h=>h.id===f.id);return C>=0?[...x.slice(0,C),f,...x.slice(C+1)]:[...x,f]}),u(!1)},y=f=>{v(new Error(f.error)),u(!1)};return t.on("message:start",m),t.on("message:chunk",S),t.on("message:answer-complete",w),t.on("message:complete",i),t.on("message:error",y),()=>{t.off("message:start",m),t.off("message:chunk",S),t.off("message:answer-complete",w),t.off("message:complete",i),t.off("message:error",y)}},[t,d]),{messages:a,isLoading:p,error:b,sendMessage:(0,s.useCallback)(async(g,m)=>{u(!0),v(null);const S={id:`temp-${Date.now()}`,conversationId:d||"",content:g,role:"user",status:"DONE",attachments:m&&m.length>0?F.attachmentsFromFiles(m):void 0,createdAt:new Date},w={id:`temp-assistant-${Date.now()}`,conversationId:d||"",content:"",role:"assistant",status:"IN_PROGRESS",createdAt:new Date};l(i=>[...i,S,w]);try{const i=await t.sendMessage(g,{conversationId:d,files:m});return i.conversationId&&!d&&c(i.conversationId),l(y=>{const f=y.filter(C=>!C.id.startsWith("temp-")),x={...S,id:S.id.replace("temp-","user-"),conversationId:i.conversationId};return f.some(C=>C.id===i.id)?[...f,x].sort((C,h)=>new Date(C.createdAt).getTime()-new Date(h.createdAt).getTime()):[...f,x,i]}),i}catch(i){return v(i instanceof Error?i:new Error("Failed to send message")),u(!1),l(y=>y.filter(f=>!f.id.startsWith("temp-"))),null}},[t,d]),clearMessages:(0,s.useCallback)(()=>{l([]),c(void 0),v(null)},[]),conversationId:d}}var q=({onSend:e,disabled:n=!1,placeholder:r="Type a message...",allowFiles:t=!1,className:a=""})=>{const[l,d]=(0,s.useState)(""),[c,p]=(0,s.useState)([]),u=(0,s.useRef)(null),b=(0,s.useRef)(null),v=(0,s.useCallback)(()=>{const i=b.current;if(!i)return;const y=110;i.style.height="auto",i.style.height=`${Math.min(i.scrollHeight+2,y)}px`,i.style.overflowY=i.scrollHeight+2>y?"auto":"hidden"},[]),I=(0,s.useCallback)(i=>{i.preventDefault(),(l.trim()||c.length>0)&&(e(l.trim(),c.length>0?c:void 0),d(""),p([]),requestAnimationFrame(v))},[l,c,e,v]),g=(0,s.useCallback)(i=>{i.key==="Enter"&&!i.shiftKey&&(i.preventDefault(),I(i))},[I]),m=(0,s.useCallback)(i=>{const y=Array.from(i.target.files||[]);p(f=>[...f,...y])},[]),S=(0,s.useCallback)(i=>{p(y=>y.filter((f,x)=>x!==i))},[]),w=l.trim()||c.length>0;return(0,o.jsxs)("form",{onSubmit:I,className:`ago-chat-input ${a}`,style:{display:"flex",flexDirection:"column",gap:"8px",padding:"12px 16px",borderTop:"1px solid #dee3e8",backgroundColor:"#fff"},children:[c.length>0&&(0,o.jsx)("div",{className:"ago-chat-input__files",style:{display:"flex",flexWrap:"wrap",gap:"6px"},children:c.map((i,y)=>(0,o.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"6px",padding:"4px 10px",backgroundColor:"#f0f2f5",borderRadius:"6px",fontSize:"12px",color:"#30373e"},children:[(0,o.jsx)("span",{style:{maxWidth:"120px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:i.name}),(0,o.jsx)("button",{type:"button",onClick:()=>S(y),"aria-label":`Remove ${i.name}`,style:{border:"none",background:"none",cursor:"pointer",padding:"0",color:"#6b6d6f",fontSize:"14px",lineHeight:1},children:"×"})]},y))}),(0,o.jsxs)("div",{style:{display:"flex",gap:"8px",alignItems:"flex-end"},children:[t&&(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("button",{type:"button",onClick:()=>u.current?.click(),disabled:n,"aria-label":"Attach file",style:{padding:"8px",border:"1px solid #dee3e8",borderRadius:"8px",backgroundColor:"#fff",cursor:n?"not-allowed":"pointer",color:"#6b6d6f",fontSize:"16px",lineHeight:1},children:"+"}),(0,o.jsx)("input",{ref:u,type:"file",multiple:!0,onChange:m,style:{display:"none"}})]}),(0,o.jsx)("textarea",{ref:b,value:l,onChange:i=>{d(i.target.value),v()},onKeyDown:g,placeholder:r,"aria-label":r,disabled:n,rows:1,style:{flex:1,padding:"10px 14px",border:"1px solid #dee3e8",borderRadius:"20px",resize:"none",outline:"none",boxSizing:"border-box",maxHeight:"110px",overflowY:"hidden",fontFamily:"inherit",fontSize:"16px",lineHeight:1.4,color:"#30373e",backgroundColor:"#f8f8f8",transition:"border-color 0.15s"},onFocus:i=>{i.currentTarget.style.borderColor="#1b5fc4"},onBlur:i=>{i.currentTarget.style.borderColor="#dee3e8"}}),(0,o.jsx)("button",{type:"submit",disabled:n||!w,style:{padding:"10px 18px",border:"none",borderRadius:"20px",backgroundColor:n||!w?"#b5bfc8":"#03182f",color:"#fff",cursor:n||!w?"not-allowed":"pointer",fontWeight:500,fontSize:"16px",transition:"background-color 0.15s"},children:"Send"})]})]})},X=({href:e,children:n,...r})=>(0,o.jsx)("a",{href:e,target:"_blank",rel:"noopener noreferrer",style:{color:"#1b5fc4",textDecoration:"underline"},...r,children:n}),Q=({children:e,...n})=>(0,o.jsx)("p",{style:{margin:"0 0 8px 0",lineHeight:"1.6"},...n,children:e}),R=(e,n)=>{const r=({children:t,...a})=>s.default.createElement(`h${e}`,{style:{margin:"16px 0 8px 0",fontSize:n,fontWeight:600,lineHeight:"1.3"},...a},t);return r.displayName=`MarkdownHeading${e}`,r},Z=({children:e,...n})=>(0,o.jsx)("ul",{style:{margin:"0 0 8px 0",paddingLeft:"20px",listStyleType:"disc",listStylePosition:"outside"},...n,children:e}),ee=({children:e,...n})=>(0,o.jsx)("ol",{style:{margin:"0 0 8px 0",paddingLeft:"20px",listStyleType:"decimal",listStylePosition:"outside"},...n,children:e}),te=({children:e,...n})=>(0,o.jsx)("li",{style:{display:"list-item",margin:"2px 0",lineHeight:"1.6"},...n,children:e}),ne=({className:e,children:n,...r})=>e!==void 0||String(n).includes(`
2
+ `)?(0,o.jsx)("code",{style:{display:"block",background:"#f5f5f5",padding:"8px 12px",borderRadius:"6px",fontSize:"13px",overflowX:"auto",fontFamily:'"IBM Plex Mono", monospace'},...r,children:n}):(0,o.jsx)("code",{style:{background:"#f0f2f5",padding:"2px 5px",borderRadius:"4px",fontSize:"13px",fontFamily:'"IBM Plex Mono", monospace'},...r,children:n}),re=({children:e,...n})=>(0,o.jsx)("pre",{style:{margin:"0 0 8px 0"},...n,children:e}),oe=({children:e,...n})=>(0,o.jsx)("blockquote",{style:{borderLeft:"4px solid #dee3e8",paddingLeft:"12px",margin:"0 0 8px 0",fontStyle:"italic",color:"#6b6d6f"},...n,children:e}),se=({children:e,...n})=>(0,o.jsx)("div",{style:{overflowX:"auto",margin:"0 0 8px 0"},children:(0,o.jsx)("table",{style:{borderCollapse:"collapse",width:"100%",fontSize:"13px"},...n,children:e})}),ae=({children:e,...n})=>(0,o.jsx)("th",{style:{border:"1px solid #dee3e8",padding:"6px 10px",textAlign:"left",backgroundColor:"#f5f7fa",fontWeight:600},...n,children:e}),ie=({children:e,...n})=>(0,o.jsx)("td",{style:{border:"1px solid #dee3e8",padding:"6px 10px"},...n,children:e}),le=({alt:e,...n})=>(0,o.jsx)("img",{alt:e??"",style:{maxWidth:"100%",borderRadius:"8px",margin:"4px 0"},...n}),ce=e=>(0,o.jsx)("hr",{style:{border:"none",borderTop:"1px solid #dee3e8",margin:"12px 0"},...e}),de={a:X,p:Q,h1:R(1,"20px"),h2:R(2,"18px"),h3:R(3,"16px"),h4:R(4,"15px"),h5:R(5,"14px"),h6:R(6,"13px"),ul:Z,ol:ee,li:te,code:ne,pre:re,blockquote:oe,table:se,th:ae,td:ie,img:le,hr:ce},ue=[T.default],$=({content:e})=>(0,o.jsx)(P.default,{remarkPlugins:ue,components:de,children:e}),fe=({attachment:e,isUser:n})=>{const r=F.safeAttachmentUrl(e.url);if(F.canInlineImage(e))return(0,o.jsx)("a",{href:r,target:"_blank",rel:"noopener noreferrer",style:{display:"inline-block",textDecoration:"none"},children:(0,o.jsx)("img",{src:r,alt:e.name,loading:"lazy",style:{maxWidth:"180px",maxHeight:"160px",objectFit:"cover",borderRadius:"10px",border:"1px solid #dee3e8",display:"block"}})});const t=F.formatFileSize(e.fileSize),a=(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("span",{style:{fontSize:"16px",lineHeight:1,flexShrink:0},"aria-hidden":!0,children:"📄"}),(0,o.jsxs)("span",{style:{display:"flex",flexDirection:"column",minWidth:0},children:[(0,o.jsx)("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",maxWidth:"160px"},title:e.name,children:e.name}),t&&(0,o.jsx)("span",{style:{fontSize:"11px",color:"#6b6d6f"},children:t})]})]}),l={display:"inline-flex",alignItems:"center",gap:"8px",padding:"8px 12px",borderRadius:"10px",border:"1px solid #dee3e8",backgroundColor:n?"rgba(255,255,255,0.12)":"#fff",color:n?"#fff":"#30373e",fontSize:"13px",textDecoration:"none",maxWidth:"220px"};return r?(0,o.jsx)("a",{href:r,target:"_blank",rel:"noopener noreferrer",style:l,children:a}):(0,o.jsx)("div",{style:l,children:a})},ge=({source:e,index:n})=>{const r=(0,o.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px",width:"100%",minWidth:0},children:[(0,o.jsx)("div",{style:{flexShrink:0,width:"18px",height:"18px",borderRadius:"3px",border:"1px solid #1b5fc4",color:"#1b5fc4",fontSize:"11px",fontWeight:500,display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"#f0f4ff"},children:n+1}),(0,o.jsx)("div",{style:{fontSize:"12px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"#30373e"},title:e.title,children:e.title})]}),t={display:"flex",alignItems:"center",padding:"8px 10px",border:"1px solid #dee3e8",borderRadius:"8px",backgroundColor:"#fff",cursor:e.url?"pointer":"default",textDecoration:"none",color:"inherit",minWidth:0,transition:"border-color 0.15s"};return e.url?(0,o.jsx)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",style:t,onMouseEnter:a=>{a.currentTarget.style.borderColor="#1b5fc4"},onMouseLeave:a=>{a.currentTarget.style.borderColor="#dee3e8"},children:r}):(0,o.jsx)("div",{style:t,children:r})},pe=()=>(0,o.jsxs)("div",{style:{display:"flex",gap:"4px",padding:"4px 0"},children:[[0,1,2].map(e=>(0,o.jsx)("div",{style:{width:"6px",height:"6px",borderRadius:"50%",backgroundColor:"#b5bfc8",animation:"ago-pulse 1.2s ease-in-out infinite",animationDelay:`${e*.2}s`}},e)),(0,o.jsx)("style",{children:`
3
3
  @keyframes ago-pulse {
4
4
  0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
5
5
  40% { opacity: 1; transform: scale(1); }
6
6
  }
7
- `})]}),$=({message:e,className:t="",showAgentName:r=!1,isLast:n=!1,onFollowUpClick:a})=>{const l=e.role==="user",d=e.status==="IN_PROGRESS";return(0,o.jsxs)("div",{className:`ago-message ago-message--${e.role} ${t}`,style:{display:"flex",flexDirection:"column",alignItems:l?"flex-end":"flex-start",marginBottom:"16px"},children:[!l&&r&&e.agent&&(0,o.jsx)("div",{className:"ago-message__agent",style:{display:"flex",alignItems:"center",gap:"6px",fontSize:"13px",fontWeight:500,color:"#30373e",marginBottom:"6px",padding:"0 4px"},children:e.agent.displayName||e.agent.name}),!l&&e.sources&&e.sources.length>0&&(0,o.jsx)("div",{className:"ago-message__sources",style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"6px",marginBottom:"10px",width:"100%",maxWidth:"85%"},children:e.sources.map((c,p)=>(0,o.jsx)(ge,{source:c,index:p},c.id))}),e.attachments&&e.attachments.length>0&&(0,o.jsx)("div",{className:"ago-message__attachments",style:{display:"flex",flexWrap:"wrap",gap:"6px",marginBottom:"6px",justifyContent:l?"flex-end":"flex-start",maxWidth:"75%"},children:e.attachments.map(c=>(0,o.jsx)(fe,{attachment:c,isUser:l},c.id))}),(e.content||d)&&(0,o.jsx)("div",{className:"ago-message__content",style:{maxWidth:l?"75%":"100%",padding:l?"10px 14px":"2px 8px",borderRadius:l?"16px":"0",backgroundColor:l?"#03182f":"transparent",color:l?"#fff":"#30373e",wordBreak:"break-word",fontSize:"16px",lineHeight:"1.6"},children:e.content?(0,o.jsx)(q,{content:e.content}):d&&(0,o.jsx)(pe,{})}),n&&e.followUpReplies&&e.followUpReplies.length>0&&(0,o.jsx)("div",{className:"ago-message__followups",style:{display:"flex",flexWrap:"wrap",gap:"8px",marginTop:"10px"},children:e.followUpReplies.map((c,p)=>(0,o.jsx)("button",{type:"button",className:"ago-message__followup-btn",disabled:!a,onClick:a?()=>a(c):void 0,style:{minHeight:"36px",padding:"6px 14px",fontSize:"13px",borderRadius:"16px",border:"1px solid #dee3e8",backgroundColor:"#fff",color:"#30373e",cursor:a?"pointer":"default",transition:"border-color 0.15s"},onMouseEnter:f=>{f.currentTarget.style.borderColor="#1b5fc4"},onMouseLeave:f=>{f.currentTarget.style.borderColor="#dee3e8"},children:c},p))})]})},xe=({client:e,conversationId:t,title:r="Chat",welcomeMessage:n="Hello! How can I help you today?",placeholder:a="Type a message...",allowFiles:l=!1,height:d=500,logoUrl:c,showAgentName:p=!1,forms:f,onFollowUpClick:v,className:x="",onMessageSent:y,onMessageReceived:h})=>{const m=(0,s.useRef)(null),C=F(),w=e??C,{messages:i,isLoading:g,error:u,sendMessage:b}=z({client:e,conversationId:t});(0,s.useEffect)(()=>{if(!w||!f||f.length===0)return;let S=!1;const E=[];return Promise.all(f.map(j=>j.schema!=null?Promise.resolve(M.createFormCollector(j)):M.loadFormCollector(w,j))).then(j=>{if(!S)for(const J of j)E.push(J.install(w))}).catch(()=>{}),()=>{S=!0,E.forEach(j=>j())}},[w,f?JSON.stringify(f.map(S=>[S.name,S.schema??null,S.submit??!1,S.description??null])):""]),(0,s.useEffect)(()=>{m.current?.scrollIntoView({behavior:"smooth"})},[i]),(0,s.useEffect)(()=>{const S=i[i.length-1];S&&S.role==="assistant"&&S.status==="DONE"&&h&&h({id:S.id,content:S.content})},[i,h]);const k=async(S,E)=>{y?.(S),await b(S,E)},P=i[i.length-1],K=g&&P?.role==="assistant"&&P.status==="IN_PROGRESS",G=v===!1?void 0:v??(S=>k(S));return(0,o.jsxs)("div",{className:`ago-chat-widget ${x}`,style:{display:"flex",flexDirection:"column",height:typeof d=="number"?`${d}px`:d,border:"1px solid #dee3e8",borderRadius:"16px",overflow:"hidden",backgroundColor:"#fff",fontFamily:'"IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',textAlign:"left",boxShadow:"rgba(15, 15, 15, 0.08) 0px 2px 16px 0px"},children:[(0,o.jsxs)("div",{className:"ago-chat-widget__header",style:{padding:"14px 16px",borderBottom:"1px solid #dee3e8",backgroundColor:"#03182f",color:"#e8f0fe",display:"flex",alignItems:"center",gap:"10px"},children:[c&&(0,o.jsx)("img",{src:c,alt:"Logo",style:{height:"24px",width:"auto"}}),(0,o.jsx)("h3",{style:{margin:0,fontSize:"15px",fontWeight:600},children:r})]}),(0,o.jsxs)("div",{className:"ago-chat-widget__messages",role:"log","aria-live":"polite","aria-relevant":"additions text","aria-atomic":!1,style:{flex:1,overflow:"auto",padding:"16px",backgroundColor:"#fbfbfb"},children:[i.length===0?(0,o.jsx)("div",{style:{textAlign:"center",color:"#6b6d6f",padding:"24px 16px",fontSize:"16px",lineHeight:"1.5"},children:n}):i.map((S,E)=>(0,o.jsx)($,{message:S,showAgentName:p,isLast:E===i.length-1,onFollowUpClick:G},S.id)),u&&(0,o.jsx)("div",{role:"alert",style:{padding:"10px 14px",backgroundColor:"#fef2f2",color:"#dc2626",borderRadius:"12px",marginTop:"8px",fontSize:"13px",border:"1px solid #fecaca"},children:u.message}),(0,o.jsx)("div",{ref:m})]}),(0,o.jsx)(H,{onSend:k,disabled:K,placeholder:a,allowFiles:l})]})};function B({client:e,autoLoad:t=!0}={}){const r=F(),n=e||r;if(!n)throw new Error("useConversation requires an AgoClient. Either pass it as options.client or wrap your app in <AgoProvider>.");const[a,l]=(0,s.useState)([]),[d,c]=(0,s.useState)(null),[p,f]=(0,s.useState)(!1),[v,x]=(0,s.useState)(null),y=(0,s.useCallback)(async()=>{f(!0),x(null);try{l(await n.getConversations())}catch(C){x(C instanceof Error?C:new Error("Failed to load conversations"))}finally{f(!1)}},[n]),h=(0,s.useCallback)(async C=>{f(!0),x(null);try{c(await n.getConversation(C))}catch(w){x(w instanceof Error?w:new Error("Failed to load conversation"))}finally{f(!1)}},[n]),m=(0,s.useCallback)(()=>{c(null)},[]);return(0,s.useEffect)(()=>{t&&y()},[t,y]),{conversations:a,currentConversation:d,isLoading:p,error:v,selectConversation:h,startNewConversation:m,refreshConversations:y}}function me(e={}){const t=F(),r=e.client||t;if(!r)throw new Error("useChat requires an AgoClient. Either pass it as options.client or wrap your app in <AgoProvider>.");const n=z({client:r,conversationId:e.conversationId}),a=B({client:r,autoLoad:e.autoLoad});return{messages:n.messages,isLoading:n.isLoading,error:n.error||a.error,sendMessage:n.sendMessage,clearMessages:n.clearMessages,conversationId:n.conversationId,conversations:a.conversations,currentConversation:a.currentConversation,isConversationsLoading:a.isLoading,selectConversation:a.selectConversation,startNewConversation:a.startNewConversation,refreshConversations:a.refreshConversations}}function he(e,t){const r=I(),{name:n,description:a,parameters:l,handler:d}=typeof e=="string"?{name:e,...t}:e,c=(0,s.useRef)(d);c.current=d,(0,s.useEffect)(()=>{const p=f=>c.current(f);return r.registerFunction(n,p,{description:a,parameters:l}),()=>{r.unregisterFunction(n)}},[r,n,a,l])}function ye(e,t){const r=I(),n=(0,s.useRef)(e);n.current=e,(0,s.useEffect)(()=>(r.registerNavigationFunction(a=>n.current(a),t),()=>{r.unregisterNavigationFunction()}),[r,t])}function be(e,t){const r=I(),n=t?.functionName??"setPageState",a=(0,s.useRef)(e);a.current=e,(0,s.useEffect)(()=>{const l=a.current.map(d=>{const c=()=>a.current.find(p=>p.name===d.name)??d;return{name:d.name,description:d.description,schema:d.schema,get:d.get?()=>c().get?.():void 0,set:p=>c().set(p)}});return r.registerPageStateFunction(l,{functionName:n}),()=>{r.unregisterPageStateFunction(n)}},[r,n])}var ve="You have navigated the user to a new page. That page now exposes its editable state through the available setPageState function, and its current values in the page context. If the user's latest request also asked to change something on this page, call setPageState now to apply exactly those changes and nothing else. Otherwise, reply with a short confirmation only.";function W(e){return{navigationFunctions:e?.navigationFunctions??["navigateToPage"],pageStateFunctionName:e?.pageStateFunctionName??"setPageState",continuationPrompt:e?.continuationPrompt??ve,maxDepth:e?.maxDepth??1,readinessTimeoutMs:e?.readinessTimeoutMs??4e3,settleMs:e?.settleMs??150,enabled:e?.enabled??!0}}function we(e){const t=I(),r=(0,s.useRef)(W(e));r.current=W(e),(0,s.useEffect)(()=>{const n={navigated:!1,depth:0,runId:0,ourSendPending:!1},a=()=>t.getRegisteredFunctions().some(x=>x.name===r.current.pageStateFunctionName),l=x=>new Promise(y=>{let h=!1;const m=g=>{h||(h=!0,clearTimeout(i),t.off("context:changed",w),y(g))},C=()=>setTimeout(()=>m(x===n.runId&&a()),r.current.settleMs),w=()=>{if(x!==n.runId)return m(!1);a()&&(t.off("context:changed",w),C())},i=setTimeout(()=>m(!1),r.current.readinessTimeoutMs);a()?C():t.on("context:changed",w)}),d=async x=>{const y=++n.runId;if(!(!await l(y)||y!==n.runId)){n.depth+=1,n.ourSendPending=!0;try{await t.sendMessage(r.current.continuationPrompt,{conversationId:x,hidden:!0})}catch{n.ourSendPending=!1}}},c=x=>{r.current.navigationFunctions.includes(x.functionName)&&(n.navigated=!0)},p=()=>{n.ourSendPending||(n.depth=0,n.runId+=1)},f=x=>{n.ourSendPending=!1;const y=n.navigated;n.navigated=!1,r.current.enabled&&y&&(n.depth>=r.current.maxDepth||d(x.conversationId))},v=()=>{n.ourSendPending=!1};return t.on("function:invoke",c),t.on("message:start",p),t.on("message:complete",f),t.on("message:error",v),()=>{n.runId+=1,t.off("function:invoke",c),t.off("message:start",p),t.off("message:complete",f),t.off("message:error",v)}},[t])}function Ce(e,t){const r=I(),n=(0,s.useId)(),a=t??n,l=(0,s.useRef)(e);l.current=e;const d=typeof e=="function";(0,s.useEffect)(()=>{if(typeof l.current=="function"){const c=()=>l.current();return r.addDynamicContext(a,c),()=>{r.removeDynamicContext(a)}}return r.setContext(a,l.current),()=>{r.removeContext(a)}},[r,a,d,d?"":JSON.stringify(e)])}function U(e){return(0,s.useSyncExternalStore)(e.subscribe,e.get,e.get)}var L={missing:[],complete:!1};function Se(e){const t=I(),r=e.schema!=null,n=JSON.stringify(e.schema??null),a=e.submit,l=a?typeof a=="string"?`client:${a}`:a.via==="backend"?"backend":"handler"in a?"client:handler":`client:${a.url}`:"none",d=JSON.stringify(e.initialValues??null),c=(0,s.useMemo)(()=>r?M.createFormCollector(e):null,[r,e.name,n,l,d,e.autoSubmit]),[p,f]=(0,s.useState)({collector:null,loading:!r,error:null});(0,s.useEffect)(()=>{if(r)return;let g=!1;return f({collector:null,loading:!0,error:null}),M.loadFormCollector(t,e).then(u=>{g||f({collector:u,loading:!1,error:null})}).catch(u=>{g||f({collector:null,loading:!1,error:u instanceof Error?u:new Error(String(u))})}),()=>{g=!0}},[t,r,e.name,l,d,e.autoSubmit]);const v=r?c:p.collector,x=r?!1:p.loading,y=r?null:p.error;(0,s.useEffect)(()=>{if(v)return v.install(t)},[t,v]);const h=(0,s.useMemo)(()=>M.createStore({values:e.initialValues??{},submitted:!1}),[d]),m=U(v?.store??h),C=(0,s.useMemo)(()=>v?.getStatus()??L,[m,v]),w=(0,s.useMemo)(()=>({...m,...C}),[m,C]),i=(0,s.useMemo)(()=>({name:e.name,store:h,functions:[],contextKey:`form:${e.name}`,contextProvider:()=>({name:`Form: ${e.name}`,description:""}),install:()=>()=>{},hydrate:()=>{},submit:async()=>({ok:!1,error:"Form definition not loaded yet."}),getValues:()=>h.get().values,setValues:()=>{},reset:()=>{},getStatus:()=>L}),[e.name,h]);return{...v??i,state:w,loading:x,error:y}}exports.AgoProvider=Y;exports.ChatInput=H;exports.ChatWidget=xe;exports.Markdown=q;exports.Message=$;exports.createFormCollector=M.createFormCollector;exports.createMockClient=V.createMockClient;exports.deriveFormStatus=M.deriveFormStatus;exports.loadFormCollector=M.loadFormCollector;exports.useAgo=O;exports.useAgoAutoContinueAfterNavigation=we;exports.useAgoClient=I;exports.useAgoContext=Ce;exports.useAgoFunction=he;exports.useAgoNavigation=ye;exports.useAgoPageState=be;exports.useAgoStore=U;exports.useChat=me;exports.useConversation=B;exports.useFormCollector=Se;exports.useMessages=z;exports.useOptionalAgoClient=F;
7
+ `})]}),B=({message:e,className:n="",showAgentName:r=!1,isLast:t=!1,onFollowUpClick:a})=>{const l=e.role==="user",d=e.status==="IN_PROGRESS"||e.status==="WAITING_CLIENT";return(0,o.jsxs)("div",{className:`ago-message ago-message--${e.role} ${n}`,style:{display:"flex",flexDirection:"column",alignItems:l?"flex-end":"flex-start",marginBottom:"16px"},children:[!l&&r&&e.agent&&(0,o.jsx)("div",{className:"ago-message__agent",style:{display:"flex",alignItems:"center",gap:"6px",fontSize:"13px",fontWeight:500,color:"#30373e",marginBottom:"6px",padding:"0 4px"},children:e.agent.displayName||e.agent.name}),!l&&e.sources&&e.sources.length>0&&(0,o.jsx)("div",{className:"ago-message__sources",style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"6px",marginBottom:"10px",width:"100%",maxWidth:"85%"},children:e.sources.map((c,p)=>(0,o.jsx)(ge,{source:c,index:p},c.id))}),e.attachments&&e.attachments.length>0&&(0,o.jsx)("div",{className:"ago-message__attachments",style:{display:"flex",flexWrap:"wrap",gap:"6px",marginBottom:"6px",justifyContent:l?"flex-end":"flex-start",maxWidth:"75%"},children:e.attachments.map(c=>(0,o.jsx)(fe,{attachment:c,isUser:l},c.id))}),(e.content||d)&&(0,o.jsx)("div",{className:"ago-message__content",style:{maxWidth:l?"75%":"100%",padding:l?"10px 14px":"2px 8px",borderRadius:l?"16px":"0",backgroundColor:l?"#03182f":"transparent",color:l?"#fff":"#30373e",wordBreak:"break-word",fontSize:"16px",lineHeight:"1.6"},children:e.content?(0,o.jsx)($,{content:e.content}):d&&(0,o.jsx)(pe,{})}),t&&e.followUpReplies&&e.followUpReplies.length>0&&(0,o.jsx)("div",{className:"ago-message__followups",style:{display:"flex",flexWrap:"wrap",gap:"8px",marginTop:"10px"},children:e.followUpReplies.map((c,p)=>(0,o.jsx)("button",{type:"button",className:"ago-message__followup-btn",disabled:!a,onClick:a?()=>a(c):void 0,style:{minHeight:"36px",padding:"6px 14px",fontSize:"13px",borderRadius:"16px",border:"1px solid #dee3e8",backgroundColor:"#fff",color:"#30373e",cursor:a?"pointer":"default",transition:"border-color 0.15s"},onMouseEnter:u=>{u.currentTarget.style.borderColor="#1b5fc4"},onMouseLeave:u=>{u.currentTarget.style.borderColor="#dee3e8"},children:c},p))})]})},xe=({client:e,conversationId:n,title:r="Chat",welcomeMessage:t="Hello! How can I help you today?",placeholder:a="Type a message...",allowFiles:l=!1,height:d=500,logoUrl:c,showAgentName:p=!1,forms:u,onFollowUpClick:b,className:v="",onMessageSent:I,onMessageReceived:g})=>{const m=(0,s.useRef)(null),S=_(),w=e??S,{messages:i,isLoading:y,error:f,sendMessage:x}=L({client:e,conversationId:n});(0,s.useEffect)(()=>{if(!w||!u||u.length===0)return;let k=!1;const A=[];return Promise.all(u.map(j=>j.schema!=null?Promise.resolve(M.createFormCollector(j)):M.loadFormCollector(w,j))).then(j=>{if(!k)for(const J of j)A.push(J.install(w))}).catch(()=>{}),()=>{k=!0,A.forEach(j=>j())}},[w,u?JSON.stringify(u.map(k=>[k.name,k.schema??null,k.submit??!1,k.description??null])):""]),(0,s.useEffect)(()=>{m.current?.scrollIntoView({behavior:"smooth"})},[i]),(0,s.useEffect)(()=>{const k=i[i.length-1];k&&k.role==="assistant"&&k.status==="DONE"&&g&&g({id:k.id,content:k.content})},[i,g]);const C=async(k,A)=>{I?.(k),await x(k,A)},h=i[i.length-1],N=y&&h?.role==="assistant"&&(h.status==="IN_PROGRESS"||h.status==="WAITING_CLIENT"),K=b===!1?void 0:b??(k=>C(k));return(0,o.jsxs)("div",{className:`ago-chat-widget ${v}`,style:{display:"flex",flexDirection:"column",height:typeof d=="number"?`${d}px`:d,border:"1px solid #dee3e8",borderRadius:"16px",overflow:"hidden",backgroundColor:"#fff",fontFamily:'"IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',textAlign:"left",boxShadow:"rgba(15, 15, 15, 0.08) 0px 2px 16px 0px"},children:[(0,o.jsxs)("div",{className:"ago-chat-widget__header",style:{padding:"14px 16px",borderBottom:"1px solid #dee3e8",backgroundColor:"#03182f",color:"#e8f0fe",display:"flex",alignItems:"center",gap:"10px"},children:[c&&(0,o.jsx)("img",{src:c,alt:"Logo",style:{height:"24px",width:"auto"}}),(0,o.jsx)("h3",{style:{margin:0,fontSize:"15px",fontWeight:600},children:r})]}),(0,o.jsxs)("div",{className:"ago-chat-widget__messages",role:"log","aria-live":"polite","aria-relevant":"additions text","aria-atomic":!1,style:{flex:1,overflow:"auto",padding:"16px",backgroundColor:"#fbfbfb"},children:[i.length===0?(0,o.jsx)("div",{style:{textAlign:"center",color:"#6b6d6f",padding:"24px 16px",fontSize:"16px",lineHeight:"1.5"},children:t}):i.map((k,A)=>(0,o.jsx)(B,{message:k,showAgentName:p,isLast:A===i.length-1,onFollowUpClick:K},k.id)),f&&(0,o.jsx)("div",{role:"alert",style:{padding:"10px 14px",backgroundColor:"#fef2f2",color:"#dc2626",borderRadius:"12px",marginTop:"8px",fontSize:"13px",border:"1px solid #fecaca"},children:f.message}),(0,o.jsx)("div",{ref:m})]}),(0,o.jsx)(q,{onSend:C,disabled:N,placeholder:a,allowFiles:l})]})};function G({client:e,autoLoad:n=!0}={}){const r=_(),t=e||r;if(!t)throw new Error("useConversation requires an AgoClient. Either pass it as options.client or wrap your app in <AgoProvider>.");const[a,l]=(0,s.useState)([]),[d,c]=(0,s.useState)(null),[p,u]=(0,s.useState)(!1),[b,v]=(0,s.useState)(null),I=(0,s.useCallback)(async()=>{u(!0),v(null);try{l(await t.getConversations())}catch(S){v(S instanceof Error?S:new Error("Failed to load conversations"))}finally{u(!1)}},[t]),g=(0,s.useCallback)(async S=>{u(!0),v(null);try{c(await t.getConversation(S))}catch(w){v(w instanceof Error?w:new Error("Failed to load conversation"))}finally{u(!1)}},[t]),m=(0,s.useCallback)(()=>{c(null)},[]);return(0,s.useEffect)(()=>{n&&I()},[n,I]),{conversations:a,currentConversation:d,isLoading:p,error:b,selectConversation:g,startNewConversation:m,refreshConversations:I}}function me(e={}){const n=_(),r=e.client||n;if(!r)throw new Error("useChat requires an AgoClient. Either pass it as options.client or wrap your app in <AgoProvider>.");const t=L({client:r,conversationId:e.conversationId}),a=G({client:r,autoLoad:e.autoLoad});return{messages:t.messages,isLoading:t.isLoading,error:t.error||a.error,sendMessage:t.sendMessage,clearMessages:t.clearMessages,conversationId:t.conversationId,conversations:a.conversations,currentConversation:a.currentConversation,isConversationsLoading:a.isLoading,selectConversation:a.selectConversation,startNewConversation:a.startNewConversation,refreshConversations:a.refreshConversations}}function he(e,n){const r=E(),{name:t,description:a,parameters:l,handler:d,maxResultBytes:c}=typeof e=="string"?{name:e,...n}:e,p=(0,s.useRef)(d);p.current=d,(0,s.useEffect)(()=>{const u=b=>p.current(b);return r.registerFunction(t,u,{description:a,parameters:l,maxResultBytes:c}),()=>{r.unregisterFunction(t)}},[r,t,a,l,c])}function ye(e,n){const r=E(),t=(0,s.useRef)(e);t.current=e,(0,s.useEffect)(()=>(r.registerNavigationFunction(a=>t.current(a),n),()=>{r.unregisterNavigationFunction()}),[r,n])}function be(e,n){const r=E(),t=n?.functionName??"setPageState",a=(0,s.useRef)(e);a.current=e,(0,s.useEffect)(()=>{const l=a.current.map(d=>{const c=()=>a.current.find(p=>p.name===d.name)??d;return{name:d.name,description:d.description,schema:d.schema,get:d.get?()=>c().get?.():void 0,set:p=>c().set(p)}});return r.registerPageStateFunction(l,{functionName:t}),()=>{r.unregisterPageStateFunction(t)}},[r,t])}var ve="You have navigated the user to a new page. That page now exposes its editable state through the available setPageState function, and its current values in the page context. If the user's latest request also asked to change something on this page, call setPageState now to apply exactly those changes and nothing else. Otherwise, reply with a short confirmation only.";function z(e){return{navigationFunctions:e?.navigationFunctions??["navigateToPage"],pageStateFunctionName:e?.pageStateFunctionName??"setPageState",continuationPrompt:e?.continuationPrompt??ve,maxDepth:e?.maxDepth??1,readinessTimeoutMs:e?.readinessTimeoutMs??4e3,settleMs:e?.settleMs??150,enabled:e?.enabled??!0}}function Ce(e){const n=E(),r=(0,s.useRef)(z(e));r.current=z(e),(0,s.useEffect)(()=>{const t={navigated:!1,pausedTurnNavigated:!1,depth:0,runId:0,ourSendPending:!1},a=()=>n.getRegisteredFunctions().some(g=>g.name===r.current.pageStateFunctionName),l=g=>new Promise(m=>{let S=!1;const w=x=>{S||(S=!0,clearTimeout(f),n.off("context:changed",y),m(x))},i=()=>setTimeout(()=>w(g===t.runId&&a()),r.current.settleMs),y=()=>{if(g!==t.runId)return w(!1);a()&&(n.off("context:changed",y),i())},f=setTimeout(()=>w(!1),r.current.readinessTimeoutMs);a()?i():n.on("context:changed",y)}),d=async g=>{const m=++t.runId;if(!(!await l(m)||m!==t.runId)){t.depth+=1,t.ourSendPending=!0;try{await n.sendMessage(r.current.continuationPrompt,{conversationId:g,hidden:!0})}catch{t.ourSendPending=!1}}},c=g=>{r.current.navigationFunctions.includes(g.functionName)&&(t.navigated=!0)},p=n.registerResumeGate(async()=>{r.current.enabled&&t.pausedTurnNavigated&&(t.pausedTurnNavigated=!1,await l(++t.runId))}),u=()=>{t.pausedTurnNavigated=t.navigated,t.navigated=!1},b=()=>{t.ourSendPending||(t.depth=0,t.runId+=1)},v=g=>{t.ourSendPending=!1;const m=t.navigated;t.navigated=!1,r.current.enabled&&m&&(t.depth>=r.current.maxDepth||d(g.conversationId))},I=()=>{t.ourSendPending=!1};return n.on("function:invoke",c),n.on("message:start",b),n.on("message:waiting-client",u),n.on("message:complete",v),n.on("message:error",I),()=>{t.runId+=1,p(),n.off("function:invoke",c),n.off("message:start",b),n.off("message:waiting-client",u),n.off("message:complete",v),n.off("message:error",I)}},[n])}function we(e,n){const r=E(),t=(0,s.useId)(),a=n??t,l=(0,s.useRef)(e);l.current=e;const d=typeof e=="function";(0,s.useEffect)(()=>{if(typeof l.current=="function"){const c=()=>l.current();return r.addDynamicContext(a,c),()=>{r.removeDynamicContext(a)}}return r.setContext(a,l.current),()=>{r.removeContext(a)}},[r,a,d,d?"":JSON.stringify(e)])}function U(e){return(0,s.useSyncExternalStore)(e.subscribe,e.get,e.get)}var O={missing:[],complete:!1};function Se(e){const n=E(),r=e.schema!=null,t=JSON.stringify(e.schema??null),a=e.submit,l=a?typeof a=="string"?`client:${a}`:a.via==="backend"?"backend":"handler"in a?"client:handler":`client:${a.url}`:"none",d=JSON.stringify(e.initialValues??null),c=(0,s.useMemo)(()=>r?M.createFormCollector(e):null,[r,e.name,t,l,d,e.autoSubmit]),[p,u]=(0,s.useState)({collector:null,loading:!r,error:null});(0,s.useEffect)(()=>{if(r)return;let y=!1;return u({collector:null,loading:!0,error:null}),M.loadFormCollector(n,e).then(f=>{y||u({collector:f,loading:!1,error:null})}).catch(f=>{y||u({collector:null,loading:!1,error:f instanceof Error?f:new Error(String(f))})}),()=>{y=!0}},[n,r,e.name,l,d,e.autoSubmit]);const b=r?c:p.collector,v=r?!1:p.loading,I=r?null:p.error;(0,s.useEffect)(()=>{if(b)return b.install(n)},[n,b]);const g=(0,s.useMemo)(()=>M.createStore({values:e.initialValues??{},submitted:!1}),[d]),m=U(b?.store??g),S=(0,s.useMemo)(()=>b?.getStatus()??O,[m,b]),w=(0,s.useMemo)(()=>({...m,...S}),[m,S]),i=(0,s.useMemo)(()=>({name:e.name,store:g,functions:[],contextKey:`form:${e.name}`,contextProvider:()=>({name:`Form: ${e.name}`,description:""}),install:()=>()=>{},hydrate:()=>{},submit:async()=>({ok:!1,error:"Form definition not loaded yet."}),getValues:()=>g.get().values,setValues:()=>{},reset:()=>{},getStatus:()=>O}),[e.name,g]);return{...b??i,state:w,loading:v,error:I}}exports.AgoProvider=Y;exports.ChatInput=q;exports.ChatWidget=xe;exports.Markdown=$;exports.Message=B;exports.createFormCollector=M.createFormCollector;exports.createMockClient=V.createMockClient;exports.deriveFormStatus=M.deriveFormStatus;exports.loadFormCollector=M.loadFormCollector;exports.useAgo=H;exports.useAgoAutoContinueAfterNavigation=Ce;exports.useAgoClient=E;exports.useAgoContext=we;exports.useAgoFunction=he;exports.useAgoNavigation=ye;exports.useAgoPageState=be;exports.useAgoStore=U;exports.useChat=me;exports.useConversation=G;exports.useFormCollector=Se;exports.useMessages=L;exports.useOptionalAgoClient=_;
package/dist/react.d.cts CHANGED
@@ -58,12 +58,45 @@ declare class AgoClient {
58
58
  private config;
59
59
  /** Conversations already warned about an empty reply (one warning each). */
60
60
  private warnedEmptyConversations;
61
+ /** Paused turns awaiting auto-resume, keyed by assistant message id. */
62
+ private pendingResumes;
63
+ /** App-provided gate deciding WHEN a paused turn resumes (see {@link registerResumeGate}). */
64
+ private resumeGate;
61
65
  constructor(config: AgoConfig);
62
66
  /**
63
67
  * Send a message and receive a streaming response
64
68
  */
65
69
  sendMessage(content: string, options?: SendMessageOptions): Promise<AgoMessage>;
66
70
  private processSSEResponse;
71
+ private resolveClientFunctionsMode;
72
+ /**
73
+ * Register a gate deciding WHEN a paused turn resumes. The SDK still decides
74
+ * *whether* (it resumes once every waiting result is submitted); the gate only
75
+ * delays the continue call — e.g. `useAgoAutoContinueAfterNavigation` waits for
76
+ * the destination page to register its page state. One gate at a time (last
77
+ * registration wins). Returns an unregister function.
78
+ */
79
+ registerResumeGate(gate: ResumeGate): () => void;
80
+ /**
81
+ * Resume a turn paused on client function results (`WAITING_CLIENT`).
82
+ *
83
+ * Sends the CURRENT page's registered functions and context — the page may
84
+ * have changed since the pause (that's the point of pausing on a navigation) —
85
+ * and streams the continuation through the same event pipeline as
86
+ * `sendMessage`, so `message:chunk` / `message:complete` (or another
87
+ * `message:waiting-client` for chained pauses) fire as usual.
88
+ *
89
+ * The SDK calls this automatically after submitting the waiting results; call
90
+ * it manually only for custom flows (e.g. after restoring a reloaded page via
91
+ * {@link resumePendingClientFunctions}).
92
+ */
93
+ continueMessage(messageId: string): Promise<AgoMessage>;
94
+ /**
95
+ * Record one of the two auto-resume preconditions for a paused turn and fire
96
+ * the resume when both are in (see {@link PendingResume}).
97
+ */
98
+ private markResumeSignal;
99
+ private runAutoResume;
67
100
  /**
68
101
  * Detect a reply that completed as DONE with no content and no activity —
69
102
  * today's backend answers an unknown `agent` slug with an empty 200, which
@@ -96,9 +129,25 @@ declare class AgoClient {
96
129
  */
97
130
  getMessages(conversationId: string): Promise<AgoMessage[]>;
98
131
  /**
99
- * Submit form data for a tool call
132
+ * Resume a turn left paused on client function results by a page reload.
133
+ *
134
+ * A paused turn (pause mode) survives a full reload: the backend keeps the
135
+ * assistant message in `WAITING_CLIENT` with its waiting tool calls. After
136
+ * restoring the conversation (`getConversation`) and re-registering the page's
137
+ * functions, call this: it re-executes each waiting client function through the
138
+ * registry, submits the results, and continues the turn.
139
+ *
140
+ * Opt-in on purpose — re-running functions on reload can be surprising (e.g. a
141
+ * navigation function would navigate again), so the app decides. Returns the
142
+ * resumed turn's final message, or `null` when there was nothing to resume or
143
+ * some waiting function is not registered on this page.
144
+ */
145
+ resumePendingClientFunctions(conversation: Conversation): Promise<AgoMessage | null>;
146
+ /**
147
+ * Submit form data for a tool call. The response's `resume` field (pause mode
148
+ * only) tells whether the paused turn is ready to be resumed.
100
149
  */
101
- submitToolCallForm(toolCallId: string, formData: Record<string, unknown>): Promise<void>;
150
+ submitToolCallForm(toolCallId: string, formData: Record<string, unknown>): Promise<SubmitToolCallResult>;
102
151
  /**
103
152
  * Confirm a tool call
104
153
  */
@@ -145,7 +194,7 @@ declare class AgoClient {
145
194
  * ```
146
195
  */
147
196
  registerFunction(definition: ClientFunctionDefinition): void;
148
- registerFunction(name: string, handler: ClientFunctionHandler, schema: Omit<ClientFunctionSchema, "name">): void;
197
+ registerFunction(name: string, handler: ClientFunctionHandler, schema: ClientFunctionRegisterOptions): void;
149
198
  /**
150
199
  * Short alias for `registerFunction`. Also accepts an array of definitions.
151
200
  *
@@ -171,6 +220,12 @@ declare class AgoClient {
171
220
  * the agent know *where* it is after it navigates (e.g. so auto-continuation
172
221
  * can apply page state on the destination), not just how to navigate away.
173
222
  *
223
+ * Routes may contain `:param` placeholders (`/users/:id`). Each distinct
224
+ * placeholder becomes a top-level string argument of `navigateToPage`
225
+ * (`{ page: "userDetail", id: "42" }`), so one route covers every detail
226
+ * page of an entity. Flat arguments only: nested object parameters are not
227
+ * reliably rendered to the model, so placeholders must not be named `page`.
228
+ *
174
229
  * @param navigate - A callback that performs the navigation (e.g. react-router's navigate)
175
230
  * @param routes - Map of route names to paths, with descriptions for the LLM
176
231
  */
@@ -338,6 +393,19 @@ declare interface AgoClientEvents {
338
393
  */
339
394
  "message:answer-complete": AgoMessage;
340
395
  "message:complete": AgoMessage;
396
+ /**
397
+ * The turn paused on client function call(s) (pause mode): the stream closed
398
+ * with status `WAITING_CLIENT` instead of `DONE`. `message:complete` does NOT
399
+ * fire for this stream — it fires when the resumed turn concludes, so one
400
+ * logical turn still emits exactly one `message:complete`. The SDK submits the
401
+ * function results and resumes automatically; listen to this to know the agent
402
+ * is waiting on the page (e.g. to keep a "working…" indicator up).
403
+ */
404
+ "message:waiting-client": {
405
+ conversationId: string;
406
+ messageId: string;
407
+ waitingToolCallIds: string[];
408
+ };
341
409
  /**
342
410
  * A reply finished as `DONE` with empty content and no tool calls, client
343
411
  * functions, or follow-up replies — usually an unknown `agent` slug (the
@@ -425,6 +493,24 @@ export declare interface AgoConfig {
425
493
  * event fires regardless of this setting.
426
494
  */
427
495
  warnOnEmptyReply?: boolean;
496
+ /**
497
+ * How the agent loop treats client function calls (requires backend support):
498
+ * - `"placeholder"` (default): the turn continues immediately on a placeholder
499
+ * result; the real result is only visible to the agent on later turns.
500
+ * - `"pause"`: the turn stops on client function call(s) with status
501
+ * `WAITING_CLIENT`; once every result is submitted, the SDK resumes the SAME
502
+ * turn via `POST /messages/{id}/continue`, so the agent sees the real results.
503
+ * Older backends ignore the flag, so `"pause"` degrades to legacy behavior.
504
+ */
505
+ clientFunctionsMode?: ClientFunctionsMode;
506
+ /**
507
+ * Max serialized size (bytes) of a client function result before the SDK
508
+ * replaces it with a flagged, truncated preview. Everything a handler
509
+ * returns is sent into the LLM context, so this caps runaway payloads
510
+ * (raw API responses, full tables). Default `50000`. Override per function
511
+ * with `maxResultBytes` on its definition; `Infinity` disables the guard.
512
+ */
513
+ maxFunctionResultBytes?: number;
428
514
  }
429
515
 
430
516
  /**
@@ -636,6 +722,12 @@ declare interface ClientFunctionDefinition {
636
722
  description: string;
637
723
  parameters: ClientFunctionSchema["parameters"];
638
724
  handler: ClientFunctionHandler;
725
+ /**
726
+ * Max serialized result size in bytes before the SDK truncates it to a
727
+ * flagged preview (default: `AgoConfig.maxFunctionResultBytes`, 50 000).
728
+ * `Infinity` disables the guard for this function.
729
+ */
730
+ maxResultBytes?: number;
639
731
  }
640
732
 
641
733
  /**
@@ -650,6 +742,20 @@ declare interface ClientFunctionInvocation {
650
742
  conversationId: string;
651
743
  }
652
744
 
745
+ /**
746
+ * Schema-plus-settings object accepted when registering a function: the schema
747
+ * (minus `name`) and SDK-side options that are NOT sent to the backend.
748
+ */
749
+ declare type ClientFunctionRegisterOptions = Omit<ClientFunctionSchema, "name"> & {
750
+ /**
751
+ * Max serialized result size in bytes before the SDK truncates it to a
752
+ * flagged preview. Overrides the client-level default
753
+ * (`AgoConfig.maxFunctionResultBytes`, 50 000 by default). `Infinity`
754
+ * disables the guard for this function.
755
+ */
756
+ maxResultBytes?: number;
757
+ };
758
+
653
759
  /**
654
760
  * Schema for a client-side function that AGO can call
655
761
  */
@@ -675,6 +781,9 @@ declare interface ClientFunctionSchema {
675
781
  };
676
782
  }
677
783
 
784
+ /** See {@link AgoConfig.clientFunctionsMode}. */
785
+ declare type ClientFunctionsMode = "placeholder" | "pause";
786
+
678
787
  /**
679
788
  * A single piece of context the client wants the LLM to know about.
680
789
  */
@@ -995,7 +1104,13 @@ export declare interface MessageProps {
995
1104
  onFollowUpClick?: (reply: string) => void;
996
1105
  }
997
1106
 
998
- declare type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCELED";
1107
+ declare type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCELED"
1108
+ /**
1109
+ * The turn paused on client function call(s) (pause mode): the agent waits for
1110
+ * every waiting call to be submitted, then the turn resumes via
1111
+ * `continueMessage`. Not a final state.
1112
+ */
1113
+ | "WAITING_CLIENT";
999
1114
 
1000
1115
  declare interface MockAgoClient extends AgoClient {
1001
1116
  /**
@@ -1027,6 +1142,17 @@ declare interface MockAgoClientOptions {
1027
1142
 
1028
1143
  declare type MockFn = (...args: any[]) => any;
1029
1144
 
1145
+ /**
1146
+ * Hook run before a paused turn is resumed, so the app controls WHEN the
1147
+ * continuation fires (e.g. wait for the destination page to mount after a
1148
+ * navigation). It must resolve — throwing or hanging blocks the resume; on
1149
+ * timeout-style situations resolve anyway and let the agent conclude.
1150
+ */
1151
+ declare type ResumeGate = (info: {
1152
+ conversationId: string;
1153
+ messageId: string;
1154
+ }) => Promise<void> | void;
1155
+
1030
1156
  /**
1031
1157
  * Options for sending a message
1032
1158
  */
@@ -1044,6 +1170,8 @@ declare interface SendMessageOptions {
1044
1170
  * Requires backend support for the `hidden` flag; older backends ignore it.
1045
1171
  */
1046
1172
  hidden?: boolean;
1173
+ /** Per-message override of {@link AgoConfig.clientFunctionsMode}. */
1174
+ clientFunctionsMode?: ClientFunctionsMode;
1047
1175
  }
1048
1176
 
1049
1177
  /**
@@ -1085,6 +1213,8 @@ declare interface SSEChunkData {
1085
1213
  follow_up_replies?: string[];
1086
1214
  satisfaction_feedback?: unknown;
1087
1215
  ask_to_talk_to_human?: boolean;
1216
+ /** Tool call ids still awaiting a client result, sent with the final `WAITING_CLIENT` event. */
1217
+ waiting_tool_call_ids?: string[];
1088
1218
  }
1089
1219
 
1090
1220
  /**
@@ -1130,6 +1260,21 @@ export declare type SubmitConfig<V = Record<string, unknown>> = string | {
1130
1260
  destination?: string;
1131
1261
  } | false;
1132
1262
 
1263
+ /**
1264
+ * Response of `POST /tool-calls/{id}/submit`. `resume` is only present when the
1265
+ * tool call belongs to a turn paused on client functions (pause mode): `ready`
1266
+ * flips to `true` once ALL waiting calls of that message are submitted, meaning
1267
+ * the turn can be resumed via `continueMessage(resume.message_id)`.
1268
+ */
1269
+ declare interface SubmitToolCallResult {
1270
+ status: string;
1271
+ result?: unknown;
1272
+ resume?: {
1273
+ message_id: string;
1274
+ ready: boolean;
1275
+ };
1276
+ }
1277
+
1133
1278
  /**
1134
1279
  * Tool call data from SSE stream
1135
1280
  */
@@ -1166,12 +1311,20 @@ export declare function useAgo(config: UseAgoOptions | null): {
1166
1311
  * Auto-continue the agent after it navigates, so a "go to page B and change X"
1167
1312
  * request completes in one user gesture. Mount this once inside `AgoProvider`.
1168
1313
  *
1169
- * How it works: when the agent calls the navigation function and that turn ends,
1170
- * this waits for the destination page's `useAgoPageState` to register (so the
1171
- * SDK will ship its `setPageState` + current state on the next send), then sends
1172
- * a hidden continuation message. The agent then applies the state in a second
1173
- * turn. The continuation is `hidden`, so it never shows in the transcript
1174
- * (requires backend support for the `hidden` flag).
1314
+ * Two mechanisms, picked by the turn's client-functions mode:
1315
+ *
1316
+ * - **Pause mode** (`clientFunctionsMode: "pause"`): the backend pauses the turn
1317
+ * on the navigation call (`message:waiting-client`) and the SDK resumes it once
1318
+ * the result is submitted. This hook only registers a *resume gate* that delays
1319
+ * the resume until the destination page's `useAgoPageState` registered (plus a
1320
+ * settle delay), so the continued turn ships the new page's `setPageState` and
1321
+ * current state. Same turn, no extra prompt, backend budget as the guardrail —
1322
+ * `continuationPrompt` and `maxDepth` are unused here.
1323
+ *
1324
+ * - **Placeholder mode** (legacy default): when the agent calls the navigation
1325
+ * function and that turn ends, this waits for the destination page's state to
1326
+ * register, then sends a hidden continuation message; the agent applies the
1327
+ * state in a second turn (requires backend support for the `hidden` flag).
1175
1328
  *
1176
1329
  * ```tsx
1177
1330
  * function AppShell() {
@@ -1274,6 +1427,12 @@ export declare interface UseAgoFunctionOptions {
1274
1427
  required?: string[];
1275
1428
  };
1276
1429
  handler: ClientFunctionHandler;
1430
+ /**
1431
+ * Max serialized result size in bytes before the SDK truncates it to a
1432
+ * flagged preview (default: `AgoConfig.maxFunctionResultBytes`, 50 000).
1433
+ * `Infinity` disables the guard for this function.
1434
+ */
1435
+ maxResultBytes?: number;
1277
1436
  }
1278
1437
 
1279
1438
  /**