@holaboss/client 0.2.0-beta.8 → 0.2.0-beta.9

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/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use client'
2
- var z=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var xe=Object.getOwnPropertyNames;var Te=Object.prototype.hasOwnProperty;var Pe=(e,t)=>{for(var o in t)z(e,o,{get:t[o],enumerable:!0})},Se=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of xe(t))!Te.call(e,n)&&n!==o&&z(e,n,{get:()=>t[n],enumerable:!(s=we(t,n))||s.enumerable});return e};var ke=e=>Se(z({},"__esModule",{value:!0}),e);var Ve={};Pe(Ve,{Chat:()=>ie,GRID_MAX_COLS:()=>L,GRID_MAX_ROWS:()=>N,HolaProvider:()=>se,PortalConflict:()=>v,bandOfKind:()=>B,bandOfType:()=>q,createApiTransport:()=>re,createHolaClient:()=>le,createPortalData:()=>ye,createWidgetTransport:()=>F,deriveFields:()=>J,footprintOf:()=>X,footprintWith:()=>j,inferSpec:()=>V,layoutSegments:()=>Y,mergeMessage:()=>Z,parseDashboardSpec:()=>Q,renderModel:()=>K,textDeltaOf:()=>I,thinkingDeltaOf:()=>W,toolEventOf:()=>M,useArtifactUrl:()=>$,useChat:()=>U,useHolaClient:()=>O,useThread:()=>he});module.exports=ke(Ve);var ee=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="message_update"?t.assistantMessageEvent??null:null},I=e=>{let t=ee(e);return t?.type==="text_delta"&&typeof t.delta=="string"?t.delta:null},W=e=>{let t=ee(e);return t?.type==="thinking_delta"&&typeof t.delta=="string"?t.delta:null},M=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="tool_execution_start"&&t.toolCallId?{phase:"start",id:t.toolCallId,name:t.toolName}:t.type==="tool_execution_end"&&t.toolCallId?{phase:"end",id:t.toolCallId,isError:t.isError}:null};var Re=/^ /,k=e=>{if(e&&typeof e=="object"){let t=e,o=typeof t.error=="string"?t.error:"request_failed";return typeof t.retryable=="boolean"?{error:o,retryable:t.retryable}:{error:o}}return{error:"request_failed"}},Ce=e=>{let t="message",o=[];for(let s of e.split(`
3
- `))s.startsWith(":")||(s.startsWith("event:")?t=s.slice(6).trim():s.startsWith("data:")&&o.push(s.slice(5).replace(Re,"")));return o.length>0?{event:t,data:o.join(`
4
- `)}:null},He=(e,t,o)=>{let s;try{s=JSON.parse(e.data)}catch{return}if(e.event==="session"){let n=s.sessionId;n&&(o(n),t.onSession?.(n));return}if(e.event==="turn_event"){t.onEvent?.(s);let n=I(s);n&&t.onText?.(n);let l=W(s);l&&t.onThinking?.(l);let r=M(s);r&&t.onTool?.(r);return}if(e.event==="chat_completed"){let n=s;o(n.sessionId),t.onComplete?.(n);return}e.event==="chat_error"&&t.onError?.(k(s))},h=async(e,t)=>{let o=await fetch(e,{headers:t});if(!o.ok)throw new Error(`hola: request failed (${o.status})`);return await o.json()},te=async e=>{let t=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body});if(!t.ok)throw new Error(`hola: message failed (${t.status})`);return await t.json()},ne=async(e,t,o,s)=>{let n=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body,signal:s});if(!(n.ok&&n.body)){t.onError?.({error:`stream_failed_${n.status}`});return}let l=n.body.getReader(),r=new TextDecoder,a="",i=()=>{let u=a.indexOf(`
2
+ var q=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var He=Object.getOwnPropertyNames;var Me=Object.prototype.hasOwnProperty;var We=(e,t)=>{for(var o in t)q(e,o,{get:t[o],enumerable:!0})},Ae=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of He(t))!Me.call(e,r)&&r!==o&&q(e,r,{get:()=>t[r],enumerable:!(s=Ie(t,r))||s.enumerable});return e};var Ee=e=>Ae(q({},"__esModule",{value:!0}),e);var rt={};We(rt,{Chat:()=>be,GRID_MAX_COLS:()=>L,GRID_MAX_ROWS:()=>N,HolaProvider:()=>ge,PortalConflict:()=>P,bandOfKind:()=>B,bandOfType:()=>Y,createApiTransport:()=>me,createHolaClient:()=>he,createPortalData:()=>Ce,createWidgetTransport:()=>F,deliverableCellText:()=>ie,deliverableStatus:()=>re,deriveFields:()=>X,footprintOf:()=>Q,footprintWith:()=>j,formatDeliverableDate:()=>le,groupDeliverableVersions:()=>G,inferSpec:()=>K,isDeliverableChecked:()=>ae,layoutSegments:()=>Z,mergeMessage:()=>ue,normalizeDeliverableColType:()=>z,normalizeDeliverableItem:()=>V,parseDashboardSpec:()=>te,parseDeliverableItems:()=>ne,parseDeliverableTable:()=>se,publishedVersionOf:()=>oe,renderModel:()=>ee,textDeltaOf:()=>I,thinkingDeltaOf:()=>H,toolEventOf:()=>M,useArtifactUrl:()=>E,useChat:()=>_,useHolaClient:()=>O,useThread:()=>Pe});module.exports=Ee(rt);var de=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="message_update"?t.assistantMessageEvent??null:null},I=e=>{let t=de(e);return t?.type==="text_delta"&&typeof t.delta=="string"?t.delta:null},H=e=>{let t=de(e);return t?.type==="thinking_delta"&&typeof t.delta=="string"?t.delta:null},M=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="tool_execution_start"&&t.toolCallId?{phase:"start",id:t.toolCallId,name:t.toolName}:t.type==="tool_execution_end"&&t.toolCallId?{phase:"end",id:t.toolCallId,isError:t.isError}:null};var $e=/^ /,D=e=>{if(e&&typeof e=="object"){let t=e,o=typeof t.error=="string"?t.error:"request_failed";return typeof t.retryable=="boolean"?{error:o,retryable:t.retryable}:{error:o}}return{error:"request_failed"}},Oe=e=>{let t="message",o=[];for(let s of e.split(`
3
+ `))s.startsWith(":")||(s.startsWith("event:")?t=s.slice(6).trim():s.startsWith("data:")&&o.push(s.slice(5).replace($e,"")));return o.length>0?{event:t,data:o.join(`
4
+ `)}:null},_e=(e,t,o)=>{let s;try{s=JSON.parse(e.data)}catch{return}if(e.event==="session"){let r=s.sessionId;r&&(o(r),t.onSession?.(r));return}if(e.event==="turn_event"){t.onEvent?.(s);let r=I(s);r&&t.onText?.(r);let a=H(s);a&&t.onThinking?.(a);let n=M(s);n&&t.onTool?.(n);return}if(e.event==="chat_completed"){let r=s;o(r.sessionId),t.onComplete?.(r);return}e.event==="chat_error"&&t.onError?.(D(s))},h=async(e,t)=>{let o=await fetch(e,{headers:t});if(!o.ok)throw new Error(`hola: request failed (${o.status})`);return await o.json()},pe=async e=>{let t=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body});if(!t.ok)throw new Error(`hola: message failed (${t.status})`);return await t.json()},ce=async(e,t,o,s)=>{let r=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body,signal:s});if(!(r.ok&&r.body)){t.onError?.({error:`stream_failed_${r.status}`});return}let a=r.body.getReader(),n=new TextDecoder,i="",l=()=>{let d=i.indexOf(`
5
5
 
6
- `);for(;u!==-1;){let b=a.slice(0,u);a=a.slice(u+2);let c=Ce(b);c&&He(c,t,o),u=a.indexOf(`
6
+ `);for(;d!==-1;){let b=i.slice(0,d);i=i.slice(d+2);let c=Oe(b);c&&_e(c,t,o),d=i.indexOf(`
7
7
 
8
- `)}},d=async()=>{let u=await l.read();if(!u.done)return a+=r.decode(u.value,{stream:!0}),i(),d()};await d()};var ve=/\/+$/,E="/api/v1/end-user",re=e=>{let t=e.baseUrl.replace(ve,""),o=()=>typeof e.token=="function"?e.token():e.token,s=r=>e.project?`${r}project=${encodeURIComponent(e.project)}`:"",n=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),l=async r=>{let a=await fetch(`${t}${E}/chat${s("?")}`,{method:"POST",headers:await n(),body:JSON.stringify({message:r})});if(!a.ok)throw new Error(`hola: message failed (${a.status})`);return{reply:(await a.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>h(`${t}${E}/chat/info${s("?")}`,await n()),sendMessage:l,streamMessage:async(r,a)=>{try{let i=await l(r);a.onText?.(i.reply),a.onComplete?.(i)}catch(i){a.onError?.(k(i))}},subscribe:(r,a)=>{let i=a?.since??"0",d=!1,u,b=a?.intervalMs??3e3,c=async()=>{try{let m=await h(`${t}${E}/chat/thread?since=${encodeURIComponent(i)}${s("&")}`,await n());for(let g of m.messages)r.onMessage(g);i=m.cursor,r.onHealthy?.()}catch(m){r.onError?.(k(m))}d||(u=setTimeout(c,b))},p=()=>{d=!0,u&&clearTimeout(u)};return a?.signal?.addEventListener("abort",p),u=setTimeout(c,0),p},requestHuman:async()=>{await fetch(`${t}${E}/chat/request-human${s("?")}`,{method:"POST",headers:await n(),body:"{}"})}}};var A=require("react"),$=(e,t)=>{let[o,s]=(0,A.useState)("");return(0,A.useEffect)(()=>{if(!e){s("");return}let n=Uint8Array.from(atob(e),r=>r.charCodeAt(0)),l=URL.createObjectURL(new Blob([n],{type:t}));return s(l),()=>URL.revokeObjectURL(l)},[e,t]),o};var _=require("react");var D=require("react"),ae=require("react/jsx-runtime"),oe=(0,D.createContext)(null),se=({client:e,children:t})=>(0,ae.jsx)(oe.Provider,{value:e,children:t}),O=()=>{let e=(0,D.useContext)(oe);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};var w=require("react"),U=e=>{let[t,o]=(0,w.useState)([]),[s,n]=(0,w.useState)(""),[l,r]=(0,w.useState)(!1),[a,i]=(0,w.useState)(null),d=(0,w.useRef)(0),u=(0,w.useCallback)(()=>{let c=d.current;return d.current+=1,c},[]);(0,w.useEffect)(()=>{let c=!0;return e.getInfo().then(p=>{c&&p.greeting&&o([{id:u(),role:"assistant",text:p.greeting}])}).catch(()=>{}),()=>{c=!1}},[e,u]);let b=(0,w.useCallback)(()=>{let c=s.trim();if(!c||l)return;n(""),i(null),r(!0);let p=u(),m=u();o(f=>[...f,{id:p,role:"user",text:c},{id:m,role:"assistant",text:"",streaming:!0}]);let g=f=>{o(T=>T.map(G=>G.id===m?f(G):G))};e.streamMessage(c,{onText:f=>g(T=>({...T,text:T.text+f})),onComplete:f=>{g(T=>({...T,text:f.reply||T.text,artifacts:f.artifacts,streaming:!1})),r(!1)},onError:f=>{g(T=>({...T,streaming:!1})),i(f.error),r(!1)}}).catch(f=>{g(T=>({...T,streaming:!1})),i(f instanceof Error?f.message:"stream_failed"),r(!1)})},[s,l,e,u]);return{messages:t,input:s,setInput:n,send:b,sending:l,error:a}};var y=require("react/jsx-runtime"),P={root:{display:"flex",flexDirection:"column",height:"100%",fontFamily:"system-ui, -apple-system, sans-serif",fontSize:14,color:"#111827"},log:{flex:1,overflowY:"auto",padding:12,display:"flex",flexDirection:"column",gap:8},user:{alignSelf:"flex-end",background:"#111827",color:"#ffffff",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},assistant:{alignSelf:"flex-start",background:"#f1f1f4",color:"#111827",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},artifacts:{display:"flex",flexDirection:"column",gap:6,marginTop:6},image:{maxHeight:220,borderRadius:8,border:"1px solid #e5e7eb"},link:{color:"#2563eb",textDecoration:"underline",wordBreak:"break-all"},error:{color:"#b91c1c",padding:"4px 12px",fontSize:13},form:{display:"flex",gap:8,borderTop:"1px solid #e5e7eb",padding:8},input:{flex:1,border:"1px solid #d1d5db",borderRadius:8,padding:"8px 10px",fontSize:14,outline:"none"},button:{border:"none",background:"#111827",color:"#ffffff",borderRadius:8,padding:"8px 14px",fontSize:14,cursor:"pointer"}},Ie=({artifact:e})=>{let t=$(e.dataBase64??"",e.mimeType),o=e.url??t;return o?e.mimeType.startsWith("image/")?(0,y.jsx)("a",{href:o,rel:"noopener noreferrer",target:"_blank",children:(0,y.jsx)("img",{alt:e.filename,src:o,style:P.image})}):(0,y.jsx)("a",{download:e.filename,href:o,style:P.link,children:e.filename}):null},ie=()=>{let e=O(),{messages:t,input:o,setInput:s,send:n,sending:l,error:r}=U(e),a=(0,_.useRef)(null);(0,_.useEffect)(()=>{let d=a.current;d&&(d.scrollTop=d.scrollHeight)},[t]);let i=d=>{d.preventDefault(),n()};return(0,y.jsxs)("div",{style:P.root,children:[(0,y.jsx)("div",{ref:a,style:P.log,children:t.map(d=>(0,y.jsxs)("div",{style:d.role==="user"?P.user:P.assistant,children:[d.text||(d.streaming?"\u2026":""),d.artifacts&&d.artifacts.length>0?(0,y.jsx)("div",{style:P.artifacts,children:d.artifacts.map(u=>(0,y.jsx)(Ie,{artifact:u},u.filename))}):null]},d.id))}),r?(0,y.jsx)("div",{style:P.error,children:r}):null,(0,y.jsxs)("form",{onSubmit:i,style:P.form,children:[(0,y.jsx)("input",{"aria-label":"Message",onChange:d=>s(d.target.value),placeholder:"Type a message\u2026",style:P.input,value:o}),(0,y.jsx)("button",{disabled:l||o.trim().length===0,style:P.button,type:"submit",children:"Send"})]})]})};var We=/\/+$/,F=e=>{let t=e.sessionId,o=e.baseUrl.replace(We,""),s=r=>`${o}/endpoint/${encodeURIComponent(e.token)}${r}`,n={"content-type":"application/json"},l=(r,a)=>({url:s(r),headers:n,body:JSON.stringify({message:a,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>h(s("/config"),{}),sendMessage:async r=>{let a=await te(l("/message",r));return t=a.sessionId,a},streamMessage:(r,a,i)=>ne(l("/message/stream",r),a,d=>{t=d},i),subscribe:(r,a)=>{let i=a?.since??"0",d=!1,u,b=a?.intervalMs??3e3,c=async()=>{let m=t;if(m)try{let g=await h(s(`/messages?session=${encodeURIComponent(m)}&since=${encodeURIComponent(i)}`),{});for(let f of g.messages)r.onMessage(f);i=g.cursor,r.onHealthy?.()}catch(g){r.onError?.(k(g))}d||(u=setTimeout(c,b))},p=()=>{d=!0,u&&clearTimeout(u)};return a?.signal?.addEventListener("abort",p),u=setTimeout(c,0),p},requestHuman:async()=>{t&&await fetch(s("/request-human"),{method:"POST",headers:n,body:JSON.stringify({sessionId:t})})}}};var le=e=>"transport"in e?e.transport:F(e);var Me=/^https?:\/\//i,Ee=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Ae=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function $e(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(Me.test(e))return"url";if(Ee.test(e))return"date"}return"text"}function J(e){let t=[],o=new Map;for(let s of e)for(let[n,l]of Object.entries(s.data??{})){if(l==null)continue;let r=o.get(n);r||(r=new Map,o.set(n,r),t.push(n));let a=$e(l);r.set(a,(r.get(a)??0)+1)}return t.map(s=>{let n=o.get(s)??new Map,l="text",r=-1;for(let[a,i]of n)i>r&&(r=i,l=a);return{key:s,label:Ae(s),type:l}})}var De=e=>typeof e=="number"?e:Number(e)||0,de=e=>/rate|position|rank|score|percent|avg/i.test(e),Oe=/posted|published|sent|completed|shipped|launched|_at|date/i,Ue=new Set(["service","order","end_user_id"]);function V(e,t){let o=e.filter(i=>!Ue.has(i.key)),s=o.filter(i=>i.type==="number").slice(0,3),n=o.find(i=>i.key==="status")??o.find(i=>i.type==="select"),l=o.find(i=>i.type==="date"&&Oe.test(i.key))??o.find(i=>i.type==="date"),r=o.filter(i=>i.type==="number"&&!de(i.key)).map(i=>({field:i,total:t.reduce((d,u)=>d+De(u.data[i.key]),0)})).sort((i,d)=>d.total-i.total).find(i=>i.total>0)?.field??null,a=[{type:"stat",label:"Items",agg:"count"}];for(let i of s){let d=de(i.key);a.push({type:"stat",metric:i.key,agg:d?"avg":"sum",label:d?`Avg ${i.label.toLowerCase()}`:i.label})}return l&&a.push({type:"line",x:l.key,y:r?.key,agg:"sum",title:r?`${r.label} by day`:"Items by day"}),n&&a.push({type:"donut",groupBy:n.key,title:n.label}),a.push({type:"table",columns:o.map(i=>i.key)}),{version:1,widgets:a}}var ue={stat:{span:1,h:1},chart:{span:2,h:2},block:{span:0,h:0}},L=6,N=4,_e=e=>Math.max(1,Math.min(L,Math.round(e))),Fe=e=>Math.max(1,Math.min(N,Math.round(e)));function B(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function q(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function X(e){return ue[e]}function j(e,t,o){let s=ue[e];return{span:t===void 0?s.span:_e(t),h:o===void 0?s.h:Fe(o)}}function Y(e){let t=[],o=null;for(let s of e){let n=B(s.kind);if(n==="block"){t.push({kind:"block",widget:s}),o=null;continue}let l=j(n,s.w,s.h),r={widget:s,span:l.span,h:l.h,band:n};o?o.cells.push(r):(o={kind:"grid",cells:[r]},t.push(o))}return t}var pe=new Set(["service","order","end_user_id"]),ce=e=>typeof e=="number"?e:Number(e)||0,ge=e=>e==null?"":String(e);function me(e,t){if(e==="count")return t.length;if(t.length===0)return 0;if(e==="last")return t[t.length-1]??0;if(e==="min")return Math.min(...t);if(e==="max")return Math.max(...t);let o=t.reduce((s,n)=>s+n,0);return e==="avg"?Math.round(o/t.length):o}function Le(e,t,o,s){let n=new Map;for(let l of e){let r=new Date(ge(l.data[t]));if(Number.isNaN(r.getTime()))continue;let a=r.toISOString().slice(0,10),i=n.get(a)??[];i.push(o?ce(l.data[o]):1),n.set(a,i)}return[...n.entries()].sort((l,r)=>l[0]<r[0]?-1:1).map(([l,r])=>({label:new Date(`${l}T00:00:00`).toLocaleDateString(void 0,{month:"short",day:"numeric"}),value:o?me(s,r):r.length}))}function Ne(e,t){let o=new Map;for(let s of e){let n=ge(s.data[t]).trim();n&&o.set(n,(o.get(n)??0)+1)}return[...o.entries()].sort((s,n)=>n[1]-s[1]).map(([s,n])=>({label:s,value:n}))}function Be(e,t,o,s){switch(e.type){case"stat":{let n=e.metric?t.get(e.metric):void 0;if(e.metric&&!n)return null;if(!n)return{kind:"stat",label:e.label??"Items",value:s.length};let l=s.map(r=>ce(r.data[n.key]));return{kind:"stat",label:e.label??n.label,value:me(e.agg??"sum",l)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let n=Le(s,e.x,e.y,e.agg??"sum");return n.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:n}}case"donut":{if(!t.has(e.groupBy))return null;let n=Ne(s,e.groupBy);return n.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:n}}case"table":{let n=e.columns?e.columns.map(l=>t.get(l)).filter(l=>l!==void 0&&!pe.has(l.key)):o;return n.length===0?null:{kind:"table",title:e.title,columns:n,rows:s}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function K(e,t,o){let s=t.filter(r=>!pe.has(r.key)),n=new Map(t.map(r=>[r.key,r])),l=[];for(let r of e.widgets){let a=Be(r,n,s,o);a&&l.push({...a,w:r.w,h:r.h})}return l}var je=new Set(["sum","avg","count","min","max","last"]),fe=e=>typeof e=="string"&&je.has(e)?e:void 0,S=e=>typeof e=="string"&&e!==""?e:void 0,C=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,H=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0;function Ge(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",label:S(t.label),metric:S(t.metric),agg:fe(t.agg),w:C(t.w),h:H(t.h)};case"line":case"bar":{let o=S(t.x);return o?{type:t.type,title:S(t.title),x:o,y:S(t.y),agg:fe(t.agg),w:C(t.w),h:H(t.h)}:null}case"donut":{let o=S(t.groupBy);return o?{type:"donut",title:S(t.title),groupBy:o,w:C(t.w),h:H(t.h)}:null}case"table":{let o=Array.isArray(t.columns)?t.columns.filter(s=>typeof s=="string"):void 0;return{type:"table",title:S(t.title),columns:o,w:C(t.w),h:H(t.h)}}case"text":{let o=S(t.body);return o?{type:"text",title:S(t.title),body:o,w:C(t.w),h:H(t.h)}:null}default:return null}}function Q(e){let t=e;if(typeof e=="string"){if(e.trim()==="")return null;try{t=JSON.parse(e)}catch{return null}}if(typeof t!="object"||t===null)return null;let o=t.widgets;if(!Array.isArray(o))return null;let s=o.map(Ge).filter(l=>l!==null);if(s.length===0)return null;let n=t.version;return{version:typeof n=="number"?n:1,title:S(t.title),widgets:s}}var ze=/\/+$/,R="/api/v1/end-user",v=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function Je(e){let t="";for(let s=0;s<e.length;s+=32768)t+=String.fromCharCode(...e.subarray(s,s+32768));return btoa(t)}var ye=e=>{let t=e.baseUrl.replace(ze,""),o=()=>typeof e.token=="function"?e.token():e.token,s=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),n=async(r,a)=>{try{let i=await fetch(`${t}${R}${r}`,{method:a.method,headers:await s(),...a.body===void 0?{}:{body:JSON.stringify(a.body)}});if(i.status===409){let d=await i.json().catch(()=>({}));throw new v(d.message??"Someone else saved this first.")}if(!i.ok){let d=await i.text().catch(()=>""),u=`${a.method} ${r} \u2192 ${String(i.status)}`;try{let b=JSON.parse(d);b.message&&(u=b.message)}catch{u=d?`${u}: ${d}`:u}throw k(new Error(u))}return await i.json()}catch(i){throw k(i)}},l=r=>`/tables/${encodeURIComponent(r)}`;return{listTables:async()=>(await h(`${t}${R}/tables`,await s())).tables,listRows:async(r,a)=>await h(`${t}${R}${l(r)}/rows?limit=${String(a??100)}`,await s()),insertRow:async(r,a)=>{let{rowIds:i}=await n(`${l(r)}/rows`,{method:"POST",body:{rows:[a]}}),d=i[0];if(!d)throw k(new Error("The row was not created."));return d},patchRow:async(r,a,i)=>(await n(`${l(r)}/rows/${encodeURIComponent(a)}`,{method:"PATCH",body:i})).updated,deleteRow:async(r,a)=>(await n(`/${encodeURIComponent(r)}/${encodeURIComponent(a)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await h(`${t}${R}/tables/files/rows?limit=200`,await s())).rows.map(a=>({id:a.rowId,filename:String(a.data.filename??""),source:String(a.data.source??"client"),campaign:String(a.data.campaign??""),size:typeof a.data.size=="number"?a.data.size:0,createdAt:a.createdAt})),uploadFile:async(r,a)=>{let i=new Uint8Array(await r.arrayBuffer());return await n("/files",{method:"POST",body:{filename:r.name,mime:r.type||"application/octet-stream",data:Je(i),...a===void 0?{}:{message:a}}})},fileLink:async r=>await h(`${t}${R}/files/${encodeURIComponent(r)}/url`,await s()),deleteFile:async r=>(await n(`/files/${encodeURIComponent(r)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await h(`${t}${R}/documents`,await s())).documents,readDocument:async r=>(await h(`${t}${R}/documents/${encodeURIComponent(r)}`,await s())).document,saveDocument:async(r,a)=>await n(`/documents/${encodeURIComponent(r)}`,{method:"PATCH",body:a})}};var x=require("react"),be="greeting";function Z(e,t){if(e.some(n=>n.id===t.id))return e;let o=e.filter(n=>n.id!==be);return[...t.author==="client"?o.filter(n=>!(n.pending&&n.author==="client"&&n.text===t.text)):o,t]}var he=(e,t)=>{let[o,s]=(0,x.useState)([]),[n,l]=(0,x.useState)(""),[r,a]=(0,x.useState)(!1),[i,d]=(0,x.useState)(null),u=(0,x.useRef)(0),b=t?.pollMs??2e3;(0,x.useEffect)(()=>{let p=!0;return e.getInfo().then(m=>{p&&m.greeting&&s(g=>g.length===0?[{id:be,cursor:"",author:"agent",text:m.greeting}]:g)}).catch(()=>{}),()=>{p=!1}},[e]),(0,x.useEffect)(()=>e.subscribe?.({onMessage:p=>s(m=>Z(m,p)),onError:p=>d(p.error),onHealthy:()=>d(null)},{intervalMs:b}),[e,b]);let c=(0,x.useCallback)(()=>{let p=n.trim();if(!p||r)return;l(""),d(null),a(!0),u.current+=1;let m={id:`pending-${u.current}`,cursor:"",author:"client",text:p,pending:!0};s(g=>[...g,m]),e.sendMessage(p).then(()=>a(!1)).catch(g=>{d(g instanceof Error?g.message:"send_failed"),a(!1)})},[n,r,e]);return{messages:o,input:n,setInput:l,send:c,sending:r,error:i}};0&&(module.exports={Chat,GRID_MAX_COLS,GRID_MAX_ROWS,HolaProvider,PortalConflict,bandOfKind,bandOfType,createApiTransport,createHolaClient,createPortalData,createWidgetTransport,deriveFields,footprintOf,footprintWith,inferSpec,layoutSegments,mergeMessage,parseDashboardSpec,renderModel,textDeltaOf,thinkingDeltaOf,toolEventOf,useArtifactUrl,useChat,useHolaClient,useThread});
8
+ `)}},u=async()=>{let d=await a.read();if(!d.done)return i+=n.decode(d.value,{stream:!0}),l(),u()};await u()};var Ue=/\/+$/,W="/api/v1/end-user",me=e=>{let t=e.baseUrl.replace(Ue,""),o=()=>typeof e.token=="function"?e.token():e.token,s=n=>e.project?`${n}project=${encodeURIComponent(e.project)}`:"",r=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),a=async n=>{let i=await fetch(`${t}${W}/chat${s("?")}`,{method:"POST",headers:await r(),body:JSON.stringify({message:n})});if(!i.ok)throw new Error(`hola: message failed (${i.status})`);return{reply:(await i.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>h(`${t}${W}/chat/info${s("?")}`,await r()),sendMessage:a,streamMessage:async(n,i)=>{try{let l=await a(n);i.onText?.(l.reply),i.onComplete?.(l)}catch(l){i.onError?.(D(l))}},subscribe:(n,i)=>{let l=i?.since??"0",u=!1,d,b=i?.intervalMs??3e3,c=async()=>{try{let f=await h(`${t}${W}/chat/thread?since=${encodeURIComponent(l)}${s("&")}`,await r());for(let m of f.messages)n.onMessage(m);l=f.cursor,n.onHealthy?.()}catch(f){n.onError?.(D(f))}u||(d=setTimeout(c,b))},p=()=>{u=!0,d&&clearTimeout(d)};return i?.signal?.addEventListener("abort",p),d=setTimeout(c,0),p},requestHuman:async()=>{await fetch(`${t}${W}/chat/request-human${s("?")}`,{method:"POST",headers:await r(),body:"{}"})}}};var A=require("react"),E=(e,t)=>{let[o,s]=(0,A.useState)("");return(0,A.useEffect)(()=>{if(!e){s("");return}let r=Uint8Array.from(atob(e),n=>n.charCodeAt(0)),a=URL.createObjectURL(new Blob([r],{type:t}));return s(a),()=>URL.revokeObjectURL(a)},[e,t]),o};var U=require("react");var $=require("react"),ye=require("react/jsx-runtime"),fe=(0,$.createContext)(null),ge=({client:e,children:t})=>(0,ye.jsx)(fe.Provider,{value:e,children:t}),O=()=>{let e=(0,$.useContext)(fe);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};var w=require("react"),_=e=>{let[t,o]=(0,w.useState)([]),[s,r]=(0,w.useState)(""),[a,n]=(0,w.useState)(!1),[i,l]=(0,w.useState)(null),u=(0,w.useRef)(0),d=(0,w.useCallback)(()=>{let c=u.current;return u.current+=1,c},[]);(0,w.useEffect)(()=>{let c=!0;return e.getInfo().then(p=>{c&&p.greeting&&o([{id:d(),role:"assistant",text:p.greeting}])}).catch(()=>{}),()=>{c=!1}},[e,d]);let b=(0,w.useCallback)(()=>{let c=s.trim();if(!c||a)return;r(""),l(null),n(!0);let p=d(),f=d();o(g=>[...g,{id:p,role:"user",text:c},{id:f,role:"assistant",text:"",streaming:!0}]);let m=g=>{o(v=>v.map(J=>J.id===f?g(J):J))};e.streamMessage(c,{onText:g=>m(v=>({...v,text:v.text+g})),onComplete:g=>{m(v=>({...v,text:g.reply||v.text,artifacts:g.artifacts,streaming:!1})),n(!1)},onError:g=>{m(v=>({...v,streaming:!1})),l(g.error),n(!1)}}).catch(g=>{m(v=>({...v,streaming:!1})),l(g instanceof Error?g.message:"stream_failed"),n(!1)})},[s,a,e,d]);return{messages:t,input:s,setInput:r,send:b,sending:a,error:i}};var y=require("react/jsx-runtime"),k={root:{display:"flex",flexDirection:"column",height:"100%",fontFamily:"system-ui, -apple-system, sans-serif",fontSize:14,color:"#111827"},log:{flex:1,overflowY:"auto",padding:12,display:"flex",flexDirection:"column",gap:8},user:{alignSelf:"flex-end",background:"#111827",color:"#ffffff",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},assistant:{alignSelf:"flex-start",background:"#f1f1f4",color:"#111827",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},artifacts:{display:"flex",flexDirection:"column",gap:6,marginTop:6},image:{maxHeight:220,borderRadius:8,border:"1px solid #e5e7eb"},link:{color:"#2563eb",textDecoration:"underline",wordBreak:"break-all"},error:{color:"#b91c1c",padding:"4px 12px",fontSize:13},form:{display:"flex",gap:8,borderTop:"1px solid #e5e7eb",padding:8},input:{flex:1,border:"1px solid #d1d5db",borderRadius:8,padding:"8px 10px",fontSize:14,outline:"none"},button:{border:"none",background:"#111827",color:"#ffffff",borderRadius:8,padding:"8px 14px",fontSize:14,cursor:"pointer"}},Fe=({artifact:e})=>{let t=E(e.dataBase64??"",e.mimeType),o=e.url??t;return o?e.mimeType.startsWith("image/")?(0,y.jsx)("a",{href:o,rel:"noopener noreferrer",target:"_blank",children:(0,y.jsx)("img",{alt:e.filename,src:o,style:k.image})}):(0,y.jsx)("a",{download:e.filename,href:o,style:k.link,children:e.filename}):null},be=()=>{let e=O(),{messages:t,input:o,setInput:s,send:r,sending:a,error:n}=_(e),i=(0,U.useRef)(null);(0,U.useEffect)(()=>{let u=i.current;u&&(u.scrollTop=u.scrollHeight)},[t]);let l=u=>{u.preventDefault(),r()};return(0,y.jsxs)("div",{style:k.root,children:[(0,y.jsx)("div",{ref:i,style:k.log,children:t.map(u=>(0,y.jsxs)("div",{style:u.role==="user"?k.user:k.assistant,children:[u.text||(u.streaming?"\u2026":""),u.artifacts&&u.artifacts.length>0?(0,y.jsx)("div",{style:k.artifacts,children:u.artifacts.map(d=>(0,y.jsx)(Fe,{artifact:d},d.filename))}):null]},u.id))}),n?(0,y.jsx)("div",{style:k.error,children:n}):null,(0,y.jsxs)("form",{onSubmit:l,style:k.form,children:[(0,y.jsx)("input",{"aria-label":"Message",onChange:u=>s(u.target.value),placeholder:"Type a message\u2026",style:k.input,value:o}),(0,y.jsx)("button",{disabled:a||o.trim().length===0,style:k.button,type:"submit",children:"Send"})]})]})};var Le=/\/+$/,F=e=>{let t=e.sessionId,o=e.baseUrl.replace(Le,""),s=n=>`${o}/endpoint/${encodeURIComponent(e.token)}${n}`,r={"content-type":"application/json"},a=(n,i)=>({url:s(n),headers:r,body:JSON.stringify({message:i,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>h(s("/config"),{}),sendMessage:async n=>{let i=await pe(a("/message",n));return t=i.sessionId,i},streamMessage:(n,i,l)=>ce(a("/message/stream",n),i,u=>{t=u},l),subscribe:(n,i)=>{let l=i?.since??"0",u=!1,d,b=i?.intervalMs??3e3,c=async()=>{let f=t;if(f)try{let m=await h(s(`/messages?session=${encodeURIComponent(f)}&since=${encodeURIComponent(l)}`),{});for(let g of m.messages)n.onMessage(g);l=m.cursor,n.onHealthy?.()}catch(m){n.onError?.(D(m))}u||(d=setTimeout(c,b))},p=()=>{u=!0,d&&clearTimeout(d)};return i?.signal?.addEventListener("abort",p),d=setTimeout(c,0),p},requestHuman:async()=>{t&&await fetch(s("/request-human"),{method:"POST",headers:r,body:JSON.stringify({sessionId:t})})}}};var he=e=>"transport"in e?e.transport:F(e);var Ne=/^https?:\/\//i,Be=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,je=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function Ve(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(Ne.test(e))return"url";if(Be.test(e))return"date"}return"text"}function X(e){let t=[],o=new Map;for(let s of e)for(let[r,a]of Object.entries(s.data??{})){if(a==null)continue;let n=o.get(r);n||(n=new Map,o.set(r,n),t.push(r));let i=Ve(a);n.set(i,(n.get(i)??0)+1)}return t.map(s=>{let r=o.get(s)??new Map,a="text",n=-1;for(let[i,l]of r)l>n&&(n=l,a=i);return{key:s,label:je(s),type:a}})}var Ge=e=>typeof e=="number"?e:Number(e)||0,we=e=>/rate|position|rank|score|percent|avg/i.test(e),ze=/posted|published|sent|completed|shipped|launched|_at|date/i,Je=new Set(["service","order","end_user_id"]);function K(e,t){let o=e.filter(l=>!Je.has(l.key)),s=o.filter(l=>l.type==="number").slice(0,3),r=o.find(l=>l.key==="status")??o.find(l=>l.type==="select"),a=o.find(l=>l.type==="date"&&ze.test(l.key))??o.find(l=>l.type==="date"),n=o.filter(l=>l.type==="number"&&!we(l.key)).map(l=>({field:l,total:t.reduce((u,d)=>u+Ge(d.data[l.key]),0)})).sort((l,u)=>u.total-l.total).find(l=>l.total>0)?.field??null,i=[{type:"stat",label:"Items",agg:"count"}];for(let l of s){let u=we(l.key);i.push({type:"stat",metric:l.key,agg:u?"avg":"sum",label:u?`Avg ${l.label.toLowerCase()}`:l.label})}return a&&i.push({type:"line",x:a.key,y:n?.key,agg:"sum",title:n?`${n.label} by day`:"Items by day"}),r&&i.push({type:"donut",groupBy:r.key,title:r.label}),i.push({type:"table",columns:o.map(l=>l.key)}),{version:1,widgets:i}}var xe={stat:{span:1,h:1},chart:{span:2,h:2},block:{span:0,h:0}},L=6,N=4,qe=e=>Math.max(1,Math.min(L,Math.round(e))),Xe=e=>Math.max(1,Math.min(N,Math.round(e)));function B(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function Y(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function Q(e){return xe[e]}function j(e,t,o){let s=xe[e];return{span:t===void 0?s.span:qe(t),h:o===void 0?s.h:Xe(o)}}function Z(e){let t=[],o=null;for(let s of e){let r=B(s.kind);if(r==="block"){t.push({kind:"block",widget:s}),o=null;continue}let a=j(r,s.w,s.h),n={widget:s,span:a.span,h:a.h,band:r};o?o.cells.push(n):(o={kind:"grid",cells:[n]},t.push(o))}return t}var ve=new Set(["service","order","end_user_id"]),ke=e=>typeof e=="number"?e:Number(e)||0,Te=e=>e==null?"":String(e);function De(e,t){if(e==="count")return t.length;if(t.length===0)return 0;if(e==="last")return t[t.length-1]??0;if(e==="min")return Math.min(...t);if(e==="max")return Math.max(...t);let o=t.reduce((s,r)=>s+r,0);return e==="avg"?Math.round(o/t.length):o}function Ke(e,t,o,s){let r=new Map;for(let a of e){let n=new Date(Te(a.data[t]));if(Number.isNaN(n.getTime()))continue;let i=n.toISOString().slice(0,10),l=r.get(i)??[];l.push(o?ke(a.data[o]):1),r.set(i,l)}return[...r.entries()].sort((a,n)=>a[0]<n[0]?-1:1).map(([a,n])=>({label:new Date(`${a}T00:00:00`).toLocaleDateString(void 0,{month:"short",day:"numeric"}),value:o?De(s,n):n.length}))}function Ye(e,t){let o=new Map;for(let s of e){let r=Te(s.data[t]).trim();r&&o.set(r,(o.get(r)??0)+1)}return[...o.entries()].sort((s,r)=>r[1]-s[1]).map(([s,r])=>({label:s,value:r}))}function Qe(e,t,o,s){switch(e.type){case"stat":{let r=e.metric?t.get(e.metric):void 0;if(e.metric&&!r)return null;if(!r)return{kind:"stat",label:e.label??"Items",value:s.length};let a=s.map(n=>ke(n.data[r.key]));return{kind:"stat",label:e.label??r.label,value:De(e.agg??"sum",a)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let r=Ke(s,e.x,e.y,e.agg??"sum");return r.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:r}}case"donut":{if(!t.has(e.groupBy))return null;let r=Ye(s,e.groupBy);return r.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:r}}case"table":{let r=e.columns?e.columns.map(a=>t.get(a)).filter(a=>a!==void 0&&!ve.has(a.key)):o;return r.length===0?null:{kind:"table",title:e.title,columns:r,rows:s}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function ee(e,t,o){let s=t.filter(n=>!ve.has(n.key)),r=new Map(t.map(n=>[n.key,n])),a=[];for(let n of e.widgets){let i=Qe(n,r,s,o);i&&a.push({...i,w:n.w,h:n.h})}return a}var Ze=new Set(["sum","avg","count","min","max","last"]),Se=e=>typeof e=="string"&&Ze.has(e)?e:void 0,T=e=>typeof e=="string"&&e!==""?e:void 0,C=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,R=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0;function et(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",label:T(t.label),metric:T(t.metric),agg:Se(t.agg),w:C(t.w),h:R(t.h)};case"line":case"bar":{let o=T(t.x);return o?{type:t.type,title:T(t.title),x:o,y:T(t.y),agg:Se(t.agg),w:C(t.w),h:R(t.h)}:null}case"donut":{let o=T(t.groupBy);return o?{type:"donut",title:T(t.title),groupBy:o,w:C(t.w),h:R(t.h)}:null}case"table":{let o=Array.isArray(t.columns)?t.columns.filter(s=>typeof s=="string"):void 0;return{type:"table",title:T(t.title),columns:o,w:C(t.w),h:R(t.h)}}case"text":{let o=T(t.body);return o?{type:"text",title:T(t.title),body:o,w:C(t.w),h:R(t.h)}:null}default:return null}}function te(e){let t=e;if(typeof e=="string"){if(e.trim()==="")return null;try{t=JSON.parse(e)}catch{return null}}if(typeof t!="object"||t===null)return null;let o=t.widgets;if(!Array.isArray(o))return null;let s=o.map(et).filter(a=>a!==null);if(s.length===0)return null;let r=t.version;return{version:typeof r=="number"?r:1,title:T(t.title),widgets:s}}function V(e){if(typeof e=="string")return e?{kind:"file",value:e}:null;if(e&&typeof e=="object"){let t=e,o=typeof t.value=="string"?t.value:"",s=t.kind==="link"||t.kind==="text"||t.kind==="table"?t.kind:"file",r=typeof t.v=="number"&&t.v>=1?Math.floor(t.v):void 0;return o?{kind:s,value:o,...r?{v:r}:{}}:null}return null}function G(e){let t=new Map;for(let o of e){let s=o.v??1,r=t.get(s)??[];r.push(o),t.set(s,r)}return[...t.entries()].sort(([o],[s])=>o-s).map(([o,s])=>({v:o,items:s}))}function ne(e){let t=e.files;if(typeof t=="string"&&t.trim()!=="")try{let s=JSON.parse(t);if(Array.isArray(s))return s.map(V).filter(r=>r!==null)}catch{}let o=String(e.file??"");return o?[{kind:"file",value:o}]:[]}function re(e,t,o){let r=(G(e).find(n=>n.v===t)?.items??[]).filter(n=>n.kind==="file").map(n=>n.value),a=r.map(n=>o.get(n)??"");return r.length===0||a.some(n=>n==="")?"awaiting":a.some(n=>n==="revise")?"revise":"accepted"}function oe(e){return Number(e.published_version)||0}function z(e){return e==="number"||e==="date"||e==="boolean"||e==="select"||e==="url"?e:e==="link"?"url":e==="checkbox"?"boolean":"text"}function se(e){try{let t=JSON.parse(e);if(Array.isArray(t.columns)&&Array.isArray(t.rows)&&t.columns.length){let o=t.columns.map((a,n)=>({key:typeof a.key=="string"&&a.key?a.key:typeof a.id=="string"&&a.id?a.id:`column_${n+1}`,label:typeof a.label=="string"?a.label:"",type:z(a.type)})),s=t.rows.map((a,n)=>({id:typeof a.id=="string"&&a.id?a.id:`row_${n}`,cells:a.cells&&typeof a.cells=="object"?a.cells:{}})),r=typeof t.name=="string"?t.name:void 0;return{columns:o,rows:s,...r?{name:r}:{}}}}catch{}return null}function ie(e){return e==null?"":String(e)}function ae(e){return e===!0||e==="true"||e==="1"||e==="yes"||e==="\u2713"}function le(e){let t=new Date(`${e}T00:00:00`);return Number.isNaN(t.getTime())?e:t.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})}var tt=/\/+$/,S="/api/v1/end-user",P=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function nt(e){let t="";for(let s=0;s<e.length;s+=32768)t+=String.fromCharCode(...e.subarray(s,s+32768));return btoa(t)}var Ce=e=>{let t=e.baseUrl.replace(tt,""),o=()=>typeof e.token=="function"?e.token():e.token,s=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),r=async(n,i)=>{try{let l=await fetch(`${t}${S}${n}`,{method:i.method,headers:await s(),...i.body===void 0?{}:{body:JSON.stringify(i.body)}});if(l.status===409){let u=await l.json().catch(()=>({}));throw new P(u.message??"Someone else saved this first.")}if(!l.ok){let u=await l.text().catch(()=>""),d=`${i.method} ${n} \u2192 ${String(l.status)}`;try{let b=JSON.parse(u);b.message&&(d=b.message)}catch{d=u?`${d}: ${u}`:d}throw D(new Error(d))}return await l.json()}catch(l){throw D(l)}},a=n=>`/tables/${encodeURIComponent(n)}`;return{listTables:async()=>(await h(`${t}${S}/tables`,await s())).tables,listRows:async(n,i)=>await h(`${t}${S}${a(n)}/rows?limit=${String(i??100)}`,await s()),insertRow:async(n,i)=>{let{rowIds:l}=await r(`${a(n)}/rows`,{method:"POST",body:{rows:[i]}}),u=l[0];if(!u)throw D(new Error("The row was not created."));return u},patchRow:async(n,i,l)=>(await r(`${a(n)}/rows/${encodeURIComponent(i)}`,{method:"PATCH",body:l})).updated,deleteRow:async(n,i)=>(await r(`/${encodeURIComponent(n)}/${encodeURIComponent(i)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await h(`${t}${S}/tables/files/rows?limit=200`,await s())).rows.map(i=>({id:i.rowId,filename:String(i.data.filename??""),source:String(i.data.source??"client"),campaign:String(i.data.campaign??""),size:typeof i.data.size=="number"?i.data.size:0,createdAt:i.createdAt})),uploadFile:async(n,i)=>{let l=new Uint8Array(await n.arrayBuffer());return await r("/files",{method:"POST",body:{filename:n.name,mime:n.type||"application/octet-stream",data:nt(l),...i===void 0?{}:{message:i}}})},fileLink:async n=>await h(`${t}${S}/files/${encodeURIComponent(n)}/url`,await s()),deleteFile:async n=>(await r(`/files/${encodeURIComponent(n)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await h(`${t}${S}/documents`,await s())).documents,readDocument:async n=>(await h(`${t}${S}/documents/${encodeURIComponent(n)}`,await s())).document,saveDocument:async(n,i)=>await r(`/documents/${encodeURIComponent(n)}`,{method:"PATCH",body:i})}};var x=require("react"),Re="greeting";function ue(e,t){if(e.some(r=>r.id===t.id))return e;let o=e.filter(r=>r.id!==Re);return[...t.author==="client"?o.filter(r=>!(r.pending&&r.author==="client"&&r.text===t.text)):o,t]}var Pe=(e,t)=>{let[o,s]=(0,x.useState)([]),[r,a]=(0,x.useState)(""),[n,i]=(0,x.useState)(!1),[l,u]=(0,x.useState)(null),d=(0,x.useRef)(0),b=t?.pollMs??2e3;(0,x.useEffect)(()=>{let p=!0;return e.getInfo().then(f=>{p&&f.greeting&&s(m=>m.length===0?[{id:Re,cursor:"",author:"agent",text:f.greeting}]:m)}).catch(()=>{}),()=>{p=!1}},[e]),(0,x.useEffect)(()=>e.subscribe?.({onMessage:p=>s(f=>ue(f,p)),onError:p=>u(p.error),onHealthy:()=>u(null)},{intervalMs:b}),[e,b]);let c=(0,x.useCallback)(()=>{let p=r.trim();if(!p||n)return;a(""),u(null),i(!0),d.current+=1;let f={id:`pending-${d.current}`,cursor:"",author:"client",text:p,pending:!0};s(m=>[...m,f]),e.sendMessage(p).then(()=>i(!1)).catch(m=>{u(m instanceof Error?m.message:"send_failed"),i(!1)})},[r,n,e]);return{messages:o,input:r,setInput:a,send:c,sending:n,error:l}};0&&(module.exports={Chat,GRID_MAX_COLS,GRID_MAX_ROWS,HolaProvider,PortalConflict,bandOfKind,bandOfType,createApiTransport,createHolaClient,createPortalData,createWidgetTransport,deliverableCellText,deliverableStatus,deriveFields,footprintOf,footprintWith,formatDeliverableDate,groupDeliverableVersions,inferSpec,isDeliverableChecked,layoutSegments,mergeMessage,normalizeDeliverableColType,normalizeDeliverableItem,parseDashboardSpec,parseDeliverableItems,parseDeliverableTable,publishedVersionOf,renderModel,textDeltaOf,thinkingDeltaOf,toolEventOf,useArtifactUrl,useChat,useHolaClient,useThread});
package/dist/index.d.cts CHANGED
@@ -452,6 +452,61 @@ type LayoutSegment = {
452
452
  * everywhere. */
453
453
  declare function layoutSegments(resolved: ResolvedWidget[]): LayoutSegment[];
454
454
 
455
+ type DeliverableItemKind = "file" | "link" | "text" | "table";
456
+ type DeliverableItem = {
457
+ kind: DeliverableItemKind;
458
+ value: string;
459
+ /** Version this item was delivered in, numbered from 1 (absent = v1). */
460
+ v?: number;
461
+ };
462
+ /** One delivered version — a bundle of items sent together, numbered from 1. */
463
+ type DeliverableVersion = {
464
+ v: number;
465
+ items: DeliverableItem[];
466
+ };
467
+ declare function normalizeDeliverableItem(x: unknown): DeliverableItem | null;
468
+ declare function groupDeliverableVersions(items: DeliverableItem[]): DeliverableVersion[];
469
+ /** Parse a deliverable row's items from its `data`. Tolerant of the legacy single `file` field and of
470
+ * bare-string refs; returns [] when there is nothing. */
471
+ declare function parseDeliverableItems(data: Record<string, unknown>): DeliverableItem[];
472
+ type DeliverableReviewState = "awaiting" | "accepted" | "revise";
473
+ declare function deliverableStatus(items: DeliverableItem[], publishedVersion: number, verdictById: Map<string, string>): DeliverableReviewState;
474
+ /** The version the client currently sees — the EXPLICIT `published_version` pointer the operator set
475
+ * (0 = nothing published). No `done → latest` fallback: that followed the latest version, so a new
476
+ * version the team delivered would auto-appear to the client before it was published. */
477
+ declare function publishedVersionOf(data: Record<string, unknown>): number;
478
+
479
+ /** A column type. `select` is an open enum edited as text; the rest drive how a cell reads. */
480
+ type DeliverableColType = "text" | "number" | "url" | "date" | "boolean" | "select";
481
+ type DeliverableColumn = {
482
+ key: string;
483
+ label: string;
484
+ type: DeliverableColType;
485
+ };
486
+ type DeliverableRow = {
487
+ id: string;
488
+ cells: Record<string, unknown>;
489
+ };
490
+ type DeliverableTable = {
491
+ /** The operator's name for this table (e.g. "Twitter influencers"). Optional for older payloads. */
492
+ name?: string;
493
+ columns: DeliverableColumn[];
494
+ rows: DeliverableRow[];
495
+ };
496
+ /** Legacy tables used `link`/`checkbox`; the current vocabulary is `url`/`boolean`. */
497
+ declare function normalizeDeliverableColType(t: unknown): DeliverableColType;
498
+ /** Parse a table item's JSON `value` into the grid model, tolerating the legacy id-keyed shape (its
499
+ * columns carried `id` not `key`, so a legacy column keeps its cells by keying on that id). Returns
500
+ * null when `value` is not a table payload. */
501
+ declare function parseDeliverableTable(value: string): DeliverableTable | null;
502
+ /** A cell value as display text (a stored null/undefined reads as empty). */
503
+ declare function deliverableCellText(v: unknown): string;
504
+ /** Whether a `boolean` cell is checked — tolerant of a real boolean or the string forms it was stored
505
+ * as across versions. */
506
+ declare function isDeliverableChecked(v: unknown): boolean;
507
+ /** A `date` cell stores YYYY-MM-DD; format it as e.g. "Aug 18, 2026" (raw string if unparseable). */
508
+ declare function formatDeliverableDate(v: string): string;
509
+
455
510
  /** Extract a streamed text delta from a raw pi turn event, or null. */
456
511
  declare const textDeltaOf: (event: unknown) => string | null;
457
512
  /** Extract a streamed reasoning delta from a raw pi turn event, or null. */
@@ -508,4 +563,4 @@ declare const useThread: (client: HolaClient, options?: {
508
563
  pollMs?: number;
509
564
  }) => UseThread;
510
565
 
511
- export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type CreateHolaClientOptions, type DashboardSpec, type DonutWidget, GRID_MAX_COLS, GRID_MAX_ROWS, type HolaArtifact, type HolaAuthor, type HolaClient, type HolaCompletion, type HolaEmployeeInfo, type HolaError, type HolaIdentity, type HolaMessage, HolaProvider, type HolaStreamHandlers, type HolaSubscribeHandlers, type HolaSubscribeOptions, type HolaToolEvent, type HolaTransport, type LaidOutWidget, type LayoutSegment, type Point, PortalConflict, type PortalData, type PortalDocument, type PortalDocumentSummary, type PortalField, type PortalFile, type PortalRow, type PortalRowPage, type PortalTable, type ResolvedWidget, type SeriesWidget, type StatView, type StatWidget, type TableWidget, type TextWidget, type ThreadMessage, type UseChat, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, createApiTransport, createHolaClient, createPortalData, createWidgetTransport, deriveFields, footprintOf, footprintWith, inferSpec, layoutSegments, mergeMessage, parseDashboardSpec, renderModel, textDeltaOf, thinkingDeltaOf, toolEventOf, useArtifactUrl, useChat, useHolaClient, useThread };
566
+ export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type CreateHolaClientOptions, type DashboardSpec, type DeliverableColType, type DeliverableColumn, type DeliverableItem, type DeliverableItemKind, type DeliverableReviewState, type DeliverableRow, type DeliverableTable, type DeliverableVersion, type DonutWidget, GRID_MAX_COLS, GRID_MAX_ROWS, type HolaArtifact, type HolaAuthor, type HolaClient, type HolaCompletion, type HolaEmployeeInfo, type HolaError, type HolaIdentity, type HolaMessage, HolaProvider, type HolaStreamHandlers, type HolaSubscribeHandlers, type HolaSubscribeOptions, type HolaToolEvent, type HolaTransport, type LaidOutWidget, type LayoutSegment, type Point, PortalConflict, type PortalData, type PortalDocument, type PortalDocumentSummary, type PortalField, type PortalFile, type PortalRow, type PortalRowPage, type PortalTable, type ResolvedWidget, type SeriesWidget, type StatView, type StatWidget, type TableWidget, type TextWidget, type ThreadMessage, type UseChat, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, createApiTransport, createHolaClient, createPortalData, createWidgetTransport, deliverableCellText, deliverableStatus, deriveFields, footprintOf, footprintWith, formatDeliverableDate, groupDeliverableVersions, inferSpec, isDeliverableChecked, layoutSegments, mergeMessage, normalizeDeliverableColType, normalizeDeliverableItem, parseDashboardSpec, parseDeliverableItems, parseDeliverableTable, publishedVersionOf, renderModel, textDeltaOf, thinkingDeltaOf, toolEventOf, useArtifactUrl, useChat, useHolaClient, useThread };
package/dist/index.d.ts CHANGED
@@ -452,6 +452,61 @@ type LayoutSegment = {
452
452
  * everywhere. */
453
453
  declare function layoutSegments(resolved: ResolvedWidget[]): LayoutSegment[];
454
454
 
455
+ type DeliverableItemKind = "file" | "link" | "text" | "table";
456
+ type DeliverableItem = {
457
+ kind: DeliverableItemKind;
458
+ value: string;
459
+ /** Version this item was delivered in, numbered from 1 (absent = v1). */
460
+ v?: number;
461
+ };
462
+ /** One delivered version — a bundle of items sent together, numbered from 1. */
463
+ type DeliverableVersion = {
464
+ v: number;
465
+ items: DeliverableItem[];
466
+ };
467
+ declare function normalizeDeliverableItem(x: unknown): DeliverableItem | null;
468
+ declare function groupDeliverableVersions(items: DeliverableItem[]): DeliverableVersion[];
469
+ /** Parse a deliverable row's items from its `data`. Tolerant of the legacy single `file` field and of
470
+ * bare-string refs; returns [] when there is nothing. */
471
+ declare function parseDeliverableItems(data: Record<string, unknown>): DeliverableItem[];
472
+ type DeliverableReviewState = "awaiting" | "accepted" | "revise";
473
+ declare function deliverableStatus(items: DeliverableItem[], publishedVersion: number, verdictById: Map<string, string>): DeliverableReviewState;
474
+ /** The version the client currently sees — the EXPLICIT `published_version` pointer the operator set
475
+ * (0 = nothing published). No `done → latest` fallback: that followed the latest version, so a new
476
+ * version the team delivered would auto-appear to the client before it was published. */
477
+ declare function publishedVersionOf(data: Record<string, unknown>): number;
478
+
479
+ /** A column type. `select` is an open enum edited as text; the rest drive how a cell reads. */
480
+ type DeliverableColType = "text" | "number" | "url" | "date" | "boolean" | "select";
481
+ type DeliverableColumn = {
482
+ key: string;
483
+ label: string;
484
+ type: DeliverableColType;
485
+ };
486
+ type DeliverableRow = {
487
+ id: string;
488
+ cells: Record<string, unknown>;
489
+ };
490
+ type DeliverableTable = {
491
+ /** The operator's name for this table (e.g. "Twitter influencers"). Optional for older payloads. */
492
+ name?: string;
493
+ columns: DeliverableColumn[];
494
+ rows: DeliverableRow[];
495
+ };
496
+ /** Legacy tables used `link`/`checkbox`; the current vocabulary is `url`/`boolean`. */
497
+ declare function normalizeDeliverableColType(t: unknown): DeliverableColType;
498
+ /** Parse a table item's JSON `value` into the grid model, tolerating the legacy id-keyed shape (its
499
+ * columns carried `id` not `key`, so a legacy column keeps its cells by keying on that id). Returns
500
+ * null when `value` is not a table payload. */
501
+ declare function parseDeliverableTable(value: string): DeliverableTable | null;
502
+ /** A cell value as display text (a stored null/undefined reads as empty). */
503
+ declare function deliverableCellText(v: unknown): string;
504
+ /** Whether a `boolean` cell is checked — tolerant of a real boolean or the string forms it was stored
505
+ * as across versions. */
506
+ declare function isDeliverableChecked(v: unknown): boolean;
507
+ /** A `date` cell stores YYYY-MM-DD; format it as e.g. "Aug 18, 2026" (raw string if unparseable). */
508
+ declare function formatDeliverableDate(v: string): string;
509
+
455
510
  /** Extract a streamed text delta from a raw pi turn event, or null. */
456
511
  declare const textDeltaOf: (event: unknown) => string | null;
457
512
  /** Extract a streamed reasoning delta from a raw pi turn event, or null. */
@@ -508,4 +563,4 @@ declare const useThread: (client: HolaClient, options?: {
508
563
  pollMs?: number;
509
564
  }) => UseThread;
510
565
 
511
- export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type CreateHolaClientOptions, type DashboardSpec, type DonutWidget, GRID_MAX_COLS, GRID_MAX_ROWS, type HolaArtifact, type HolaAuthor, type HolaClient, type HolaCompletion, type HolaEmployeeInfo, type HolaError, type HolaIdentity, type HolaMessage, HolaProvider, type HolaStreamHandlers, type HolaSubscribeHandlers, type HolaSubscribeOptions, type HolaToolEvent, type HolaTransport, type LaidOutWidget, type LayoutSegment, type Point, PortalConflict, type PortalData, type PortalDocument, type PortalDocumentSummary, type PortalField, type PortalFile, type PortalRow, type PortalRowPage, type PortalTable, type ResolvedWidget, type SeriesWidget, type StatView, type StatWidget, type TableWidget, type TextWidget, type ThreadMessage, type UseChat, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, createApiTransport, createHolaClient, createPortalData, createWidgetTransport, deriveFields, footprintOf, footprintWith, inferSpec, layoutSegments, mergeMessage, parseDashboardSpec, renderModel, textDeltaOf, thinkingDeltaOf, toolEventOf, useArtifactUrl, useChat, useHolaClient, useThread };
566
+ export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type CreateHolaClientOptions, type DashboardSpec, type DeliverableColType, type DeliverableColumn, type DeliverableItem, type DeliverableItemKind, type DeliverableReviewState, type DeliverableRow, type DeliverableTable, type DeliverableVersion, type DonutWidget, GRID_MAX_COLS, GRID_MAX_ROWS, type HolaArtifact, type HolaAuthor, type HolaClient, type HolaCompletion, type HolaEmployeeInfo, type HolaError, type HolaIdentity, type HolaMessage, HolaProvider, type HolaStreamHandlers, type HolaSubscribeHandlers, type HolaSubscribeOptions, type HolaToolEvent, type HolaTransport, type LaidOutWidget, type LayoutSegment, type Point, PortalConflict, type PortalData, type PortalDocument, type PortalDocumentSummary, type PortalField, type PortalFile, type PortalRow, type PortalRowPage, type PortalTable, type ResolvedWidget, type SeriesWidget, type StatView, type StatWidget, type TableWidget, type TextWidget, type ThreadMessage, type UseChat, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, createApiTransport, createHolaClient, createPortalData, createWidgetTransport, deliverableCellText, deliverableStatus, deriveFields, footprintOf, footprintWith, formatDeliverableDate, groupDeliverableVersions, inferSpec, isDeliverableChecked, layoutSegments, mergeMessage, normalizeDeliverableColType, normalizeDeliverableItem, parseDashboardSpec, parseDeliverableItems, parseDeliverableTable, publishedVersionOf, renderModel, textDeltaOf, thinkingDeltaOf, toolEventOf, useArtifactUrl, useChat, useHolaClient, useThread };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  'use client'
2
- var j=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="message_update"?t.assistantMessageEvent??null:null},M=e=>{let t=j(e);return t?.type==="text_delta"&&typeof t.delta=="string"?t.delta:null},E=e=>{let t=j(e);return t?.type==="thinking_delta"&&typeof t.delta=="string"?t.delta:null},A=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="tool_execution_start"&&t.toolCallId?{phase:"start",id:t.toolCallId,name:t.toolName}:t.type==="tool_execution_end"&&t.toolCallId?{phase:"end",id:t.toolCallId,isError:t.isError}:null};var pe=/^ /,T=e=>{if(e&&typeof e=="object"){let t=e,s=typeof t.error=="string"?t.error:"request_failed";return typeof t.retryable=="boolean"?{error:s,retryable:t.retryable}:{error:s}}return{error:"request_failed"}},ce=e=>{let t="message",s=[];for(let o of e.split(`
3
- `))o.startsWith(":")||(o.startsWith("event:")?t=o.slice(6).trim():o.startsWith("data:")&&s.push(o.slice(5).replace(pe,"")));return s.length>0?{event:t,data:s.join(`
4
- `)}:null},ge=(e,t,s)=>{let o;try{o=JSON.parse(e.data)}catch{return}if(e.event==="session"){let r=o.sessionId;r&&(s(r),t.onSession?.(r));return}if(e.event==="turn_event"){t.onEvent?.(o);let r=M(o);r&&t.onText?.(r);let l=E(o);l&&t.onThinking?.(l);let n=A(o);n&&t.onTool?.(n);return}if(e.event==="chat_completed"){let r=o;s(r.sessionId),t.onComplete?.(r);return}e.event==="chat_error"&&t.onError?.(T(o))},b=async(e,t)=>{let s=await fetch(e,{headers:t});if(!s.ok)throw new Error(`hola: request failed (${s.status})`);return await s.json()},G=async e=>{let t=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body});if(!t.ok)throw new Error(`hola: message failed (${t.status})`);return await t.json()},z=async(e,t,s,o)=>{let r=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body,signal:o});if(!(r.ok&&r.body)){t.onError?.({error:`stream_failed_${r.status}`});return}let l=r.body.getReader(),n=new TextDecoder,a="",i=()=>{let u=a.indexOf(`
2
+ var z=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="message_update"?t.assistantMessageEvent??null:null},M=e=>{let t=z(e);return t?.type==="text_delta"&&typeof t.delta=="string"?t.delta:null},W=e=>{let t=z(e);return t?.type==="thinking_delta"&&typeof t.delta=="string"?t.delta:null},A=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="tool_execution_start"&&t.toolCallId?{phase:"start",id:t.toolCallId,name:t.toolName}:t.type==="tool_execution_end"&&t.toolCallId?{phase:"end",id:t.toolCallId,isError:t.isError}:null};var ve=/^ /,v=e=>{if(e&&typeof e=="object"){let t=e,o=typeof t.error=="string"?t.error:"request_failed";return typeof t.retryable=="boolean"?{error:o,retryable:t.retryable}:{error:o}}return{error:"request_failed"}},ke=e=>{let t="message",o=[];for(let s of e.split(`
3
+ `))s.startsWith(":")||(s.startsWith("event:")?t=s.slice(6).trim():s.startsWith("data:")&&o.push(s.slice(5).replace(ve,"")));return o.length>0?{event:t,data:o.join(`
4
+ `)}:null},Te=(e,t,o)=>{let s;try{s=JSON.parse(e.data)}catch{return}if(e.event==="session"){let r=s.sessionId;r&&(o(r),t.onSession?.(r));return}if(e.event==="turn_event"){t.onEvent?.(s);let r=M(s);r&&t.onText?.(r);let a=W(s);a&&t.onThinking?.(a);let n=A(s);n&&t.onTool?.(n);return}if(e.event==="chat_completed"){let r=s;o(r.sessionId),t.onComplete?.(r);return}e.event==="chat_error"&&t.onError?.(v(s))},b=async(e,t)=>{let o=await fetch(e,{headers:t});if(!o.ok)throw new Error(`hola: request failed (${o.status})`);return await o.json()},J=async e=>{let t=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body});if(!t.ok)throw new Error(`hola: message failed (${t.status})`);return await t.json()},q=async(e,t,o,s)=>{let r=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body,signal:s});if(!(r.ok&&r.body)){t.onError?.({error:`stream_failed_${r.status}`});return}let a=r.body.getReader(),n=new TextDecoder,i="",l=()=>{let d=i.indexOf(`
5
5
 
6
- `);for(;u!==-1;){let y=a.slice(0,u);a=a.slice(u+2);let c=ce(y);c&&ge(c,t,s),u=a.indexOf(`
6
+ `);for(;d!==-1;){let y=i.slice(0,d);i=i.slice(d+2);let c=ke(y);c&&Te(c,t,o),d=i.indexOf(`
7
7
 
8
- `)}},d=async()=>{let u=await l.read();if(!u.done)return a+=n.decode(u.value,{stream:!0}),i(),d()};await d()};var me=/\/+$/,C="/api/v1/end-user",fe=e=>{let t=e.baseUrl.replace(me,""),s=()=>typeof e.token=="function"?e.token():e.token,o=n=>e.project?`${n}project=${encodeURIComponent(e.project)}`:"",r=async()=>({"content-type":"application/json",authorization:`Bearer ${await s()}`}),l=async n=>{let a=await fetch(`${t}${C}/chat${o("?")}`,{method:"POST",headers:await r(),body:JSON.stringify({message:n})});if(!a.ok)throw new Error(`hola: message failed (${a.status})`);return{reply:(await a.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>b(`${t}${C}/chat/info${o("?")}`,await r()),sendMessage:l,streamMessage:async(n,a)=>{try{let i=await l(n);a.onText?.(i.reply),a.onComplete?.(i)}catch(i){a.onError?.(T(i))}},subscribe:(n,a)=>{let i=a?.since??"0",d=!1,u,y=a?.intervalMs??3e3,c=async()=>{try{let m=await b(`${t}${C}/chat/thread?since=${encodeURIComponent(i)}${o("&")}`,await r());for(let g of m.messages)n.onMessage(g);i=m.cursor,n.onHealthy?.()}catch(m){n.onError?.(T(m))}d||(u=setTimeout(c,y))},p=()=>{d=!0,u&&clearTimeout(u)};return a?.signal?.addEventListener("abort",p),u=setTimeout(c,0),p},requestHuman:async()=>{await fetch(`${t}${C}/chat/request-human${o("?")}`,{method:"POST",headers:await r(),body:"{}"})}}};import{useEffect as ye,useState as be}from"react";var $=(e,t)=>{let[s,o]=be("");return ye(()=>{if(!e){o("");return}let r=Uint8Array.from(atob(e),n=>n.charCodeAt(0)),l=URL.createObjectURL(new Blob([r],{type:t}));return o(l),()=>URL.revokeObjectURL(l)},[e,t]),s};import{useEffect as ke,useRef as Re}from"react";import{createContext as he,useContext as we}from"react";import{jsx as Te}from"react/jsx-runtime";var J=he(null),xe=({client:e,children:t})=>Te(J.Provider,{value:e,children:t}),D=()=>{let e=we(J);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};import{useCallback as V,useEffect as Pe,useRef as Se,useState as H}from"react";var O=e=>{let[t,s]=H([]),[o,r]=H(""),[l,n]=H(!1),[a,i]=H(null),d=Se(0),u=V(()=>{let c=d.current;return d.current+=1,c},[]);Pe(()=>{let c=!0;return e.getInfo().then(p=>{c&&p.greeting&&s([{id:u(),role:"assistant",text:p.greeting}])}).catch(()=>{}),()=>{c=!1}},[e,u]);let y=V(()=>{let c=o.trim();if(!c||l)return;r(""),i(null),n(!0);let p=u(),m=u();s(f=>[...f,{id:p,role:"user",text:c},{id:m,role:"assistant",text:"",streaming:!0}]);let g=f=>{s(h=>h.map(W=>W.id===m?f(W):W))};e.streamMessage(c,{onText:f=>g(h=>({...h,text:h.text+f})),onComplete:f=>{g(h=>({...h,text:f.reply||h.text,artifacts:f.artifacts,streaming:!1})),n(!1)},onError:f=>{g(h=>({...h,streaming:!1})),i(f.error),n(!1)}}).catch(f=>{g(h=>({...h,streaming:!1})),i(f instanceof Error?f.message:"stream_failed"),n(!1)})},[o,l,e,u]);return{messages:t,input:o,setInput:r,send:y,sending:l,error:a}};import{jsx as P,jsxs as U}from"react/jsx-runtime";var w={root:{display:"flex",flexDirection:"column",height:"100%",fontFamily:"system-ui, -apple-system, sans-serif",fontSize:14,color:"#111827"},log:{flex:1,overflowY:"auto",padding:12,display:"flex",flexDirection:"column",gap:8},user:{alignSelf:"flex-end",background:"#111827",color:"#ffffff",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},assistant:{alignSelf:"flex-start",background:"#f1f1f4",color:"#111827",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},artifacts:{display:"flex",flexDirection:"column",gap:6,marginTop:6},image:{maxHeight:220,borderRadius:8,border:"1px solid #e5e7eb"},link:{color:"#2563eb",textDecoration:"underline",wordBreak:"break-all"},error:{color:"#b91c1c",padding:"4px 12px",fontSize:13},form:{display:"flex",gap:8,borderTop:"1px solid #e5e7eb",padding:8},input:{flex:1,border:"1px solid #d1d5db",borderRadius:8,padding:"8px 10px",fontSize:14,outline:"none"},button:{border:"none",background:"#111827",color:"#ffffff",borderRadius:8,padding:"8px 14px",fontSize:14,cursor:"pointer"}},Ce=({artifact:e})=>{let t=$(e.dataBase64??"",e.mimeType),s=e.url??t;return s?e.mimeType.startsWith("image/")?P("a",{href:s,rel:"noopener noreferrer",target:"_blank",children:P("img",{alt:e.filename,src:s,style:w.image})}):P("a",{download:e.filename,href:s,style:w.link,children:e.filename}):null},He=()=>{let e=D(),{messages:t,input:s,setInput:o,send:r,sending:l,error:n}=O(e),a=Re(null);ke(()=>{let d=a.current;d&&(d.scrollTop=d.scrollHeight)},[t]);let i=d=>{d.preventDefault(),r()};return U("div",{style:w.root,children:[P("div",{ref:a,style:w.log,children:t.map(d=>U("div",{style:d.role==="user"?w.user:w.assistant,children:[d.text||(d.streaming?"\u2026":""),d.artifacts&&d.artifacts.length>0?P("div",{style:w.artifacts,children:d.artifacts.map(u=>P(Ce,{artifact:u},u.filename))}):null]},d.id))}),n?P("div",{style:w.error,children:n}):null,U("form",{onSubmit:i,style:w.form,children:[P("input",{"aria-label":"Message",onChange:d=>o(d.target.value),placeholder:"Type a message\u2026",style:w.input,value:s}),P("button",{disabled:l||s.trim().length===0,style:w.button,type:"submit",children:"Send"})]})]})};var ve=/\/+$/,_=e=>{let t=e.sessionId,s=e.baseUrl.replace(ve,""),o=n=>`${s}/endpoint/${encodeURIComponent(e.token)}${n}`,r={"content-type":"application/json"},l=(n,a)=>({url:o(n),headers:r,body:JSON.stringify({message:a,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>b(o("/config"),{}),sendMessage:async n=>{let a=await G(l("/message",n));return t=a.sessionId,a},streamMessage:(n,a,i)=>z(l("/message/stream",n),a,d=>{t=d},i),subscribe:(n,a)=>{let i=a?.since??"0",d=!1,u,y=a?.intervalMs??3e3,c=async()=>{let m=t;if(m)try{let g=await b(o(`/messages?session=${encodeURIComponent(m)}&since=${encodeURIComponent(i)}`),{});for(let f of g.messages)n.onMessage(f);i=g.cursor,n.onHealthy?.()}catch(g){n.onError?.(T(g))}d||(u=setTimeout(c,y))},p=()=>{d=!0,u&&clearTimeout(u)};return a?.signal?.addEventListener("abort",p),u=setTimeout(c,0),p},requestHuman:async()=>{t&&await fetch(o("/request-human"),{method:"POST",headers:r,body:JSON.stringify({sessionId:t})})}}};var Ie=e=>"transport"in e?e.transport:_(e);var We=/^https?:\/\//i,Me=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Ee=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function Ae(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(We.test(e))return"url";if(Me.test(e))return"date"}return"text"}function q(e){let t=[],s=new Map;for(let o of e)for(let[r,l]of Object.entries(o.data??{})){if(l==null)continue;let n=s.get(r);n||(n=new Map,s.set(r,n),t.push(r));let a=Ae(l);n.set(a,(n.get(a)??0)+1)}return t.map(o=>{let r=s.get(o)??new Map,l="text",n=-1;for(let[a,i]of r)i>n&&(n=i,l=a);return{key:o,label:Ee(o),type:l}})}var $e=e=>typeof e=="number"?e:Number(e)||0,X=e=>/rate|position|rank|score|percent|avg/i.test(e),De=/posted|published|sent|completed|shipped|launched|_at|date/i,Oe=new Set(["service","order","end_user_id"]);function Y(e,t){let s=e.filter(i=>!Oe.has(i.key)),o=s.filter(i=>i.type==="number").slice(0,3),r=s.find(i=>i.key==="status")??s.find(i=>i.type==="select"),l=s.find(i=>i.type==="date"&&De.test(i.key))??s.find(i=>i.type==="date"),n=s.filter(i=>i.type==="number"&&!X(i.key)).map(i=>({field:i,total:t.reduce((d,u)=>d+$e(u.data[i.key]),0)})).sort((i,d)=>d.total-i.total).find(i=>i.total>0)?.field??null,a=[{type:"stat",label:"Items",agg:"count"}];for(let i of o){let d=X(i.key);a.push({type:"stat",metric:i.key,agg:d?"avg":"sum",label:d?`Avg ${i.label.toLowerCase()}`:i.label})}return l&&a.push({type:"line",x:l.key,y:n?.key,agg:"sum",title:n?`${n.label} by day`:"Items by day"}),r&&a.push({type:"donut",groupBy:r.key,title:r.label}),a.push({type:"table",columns:s.map(i=>i.key)}),{version:1,widgets:a}}var K={stat:{span:1,h:1},chart:{span:2,h:2},block:{span:0,h:0}},F=6,L=4,Ue=e=>Math.max(1,Math.min(F,Math.round(e))),_e=e=>Math.max(1,Math.min(L,Math.round(e)));function N(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function Q(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function Z(e){return K[e]}function B(e,t,s){let o=K[e];return{span:t===void 0?o.span:Ue(t),h:s===void 0?o.h:_e(s)}}function ee(e){let t=[],s=null;for(let o of e){let r=N(o.kind);if(r==="block"){t.push({kind:"block",widget:o}),s=null;continue}let l=B(r,o.w,o.h),n={widget:o,span:l.span,h:l.h,band:r};s?s.cells.push(n):(s={kind:"grid",cells:[n]},t.push(s))}return t}var te=new Set(["service","order","end_user_id"]),ne=e=>typeof e=="number"?e:Number(e)||0,re=e=>e==null?"":String(e);function oe(e,t){if(e==="count")return t.length;if(t.length===0)return 0;if(e==="last")return t[t.length-1]??0;if(e==="min")return Math.min(...t);if(e==="max")return Math.max(...t);let s=t.reduce((o,r)=>o+r,0);return e==="avg"?Math.round(s/t.length):s}function Fe(e,t,s,o){let r=new Map;for(let l of e){let n=new Date(re(l.data[t]));if(Number.isNaN(n.getTime()))continue;let a=n.toISOString().slice(0,10),i=r.get(a)??[];i.push(s?ne(l.data[s]):1),r.set(a,i)}return[...r.entries()].sort((l,n)=>l[0]<n[0]?-1:1).map(([l,n])=>({label:new Date(`${l}T00:00:00`).toLocaleDateString(void 0,{month:"short",day:"numeric"}),value:s?oe(o,n):n.length}))}function Le(e,t){let s=new Map;for(let o of e){let r=re(o.data[t]).trim();r&&s.set(r,(s.get(r)??0)+1)}return[...s.entries()].sort((o,r)=>r[1]-o[1]).map(([o,r])=>({label:o,value:r}))}function Ne(e,t,s,o){switch(e.type){case"stat":{let r=e.metric?t.get(e.metric):void 0;if(e.metric&&!r)return null;if(!r)return{kind:"stat",label:e.label??"Items",value:o.length};let l=o.map(n=>ne(n.data[r.key]));return{kind:"stat",label:e.label??r.label,value:oe(e.agg??"sum",l)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let r=Fe(o,e.x,e.y,e.agg??"sum");return r.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:r}}case"donut":{if(!t.has(e.groupBy))return null;let r=Le(o,e.groupBy);return r.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:r}}case"table":{let r=e.columns?e.columns.map(l=>t.get(l)).filter(l=>l!==void 0&&!te.has(l.key)):s;return r.length===0?null:{kind:"table",title:e.title,columns:r,rows:o}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function se(e,t,s){let o=t.filter(n=>!te.has(n.key)),r=new Map(t.map(n=>[n.key,n])),l=[];for(let n of e.widgets){let a=Ne(n,r,o,s);a&&l.push({...a,w:n.w,h:n.h})}return l}var Be=new Set(["sum","avg","count","min","max","last"]),ae=e=>typeof e=="string"&&Be.has(e)?e:void 0,x=e=>typeof e=="string"&&e!==""?e:void 0,k=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,R=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0;function je(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",label:x(t.label),metric:x(t.metric),agg:ae(t.agg),w:k(t.w),h:R(t.h)};case"line":case"bar":{let s=x(t.x);return s?{type:t.type,title:x(t.title),x:s,y:x(t.y),agg:ae(t.agg),w:k(t.w),h:R(t.h)}:null}case"donut":{let s=x(t.groupBy);return s?{type:"donut",title:x(t.title),groupBy:s,w:k(t.w),h:R(t.h)}:null}case"table":{let s=Array.isArray(t.columns)?t.columns.filter(o=>typeof o=="string"):void 0;return{type:"table",title:x(t.title),columns:s,w:k(t.w),h:R(t.h)}}case"text":{let s=x(t.body);return s?{type:"text",title:x(t.title),body:s,w:k(t.w),h:R(t.h)}:null}default:return null}}function ie(e){let t=e;if(typeof e=="string"){if(e.trim()==="")return null;try{t=JSON.parse(e)}catch{return null}}if(typeof t!="object"||t===null)return null;let s=t.widgets;if(!Array.isArray(s))return null;let o=s.map(je).filter(l=>l!==null);if(o.length===0)return null;let r=t.version;return{version:typeof r=="number"?r:1,title:x(t.title),widgets:o}}var Ge=/\/+$/,S="/api/v1/end-user",v=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function ze(e){let t="";for(let o=0;o<e.length;o+=32768)t+=String.fromCharCode(...e.subarray(o,o+32768));return btoa(t)}var Je=e=>{let t=e.baseUrl.replace(Ge,""),s=()=>typeof e.token=="function"?e.token():e.token,o=async()=>({"content-type":"application/json",authorization:`Bearer ${await s()}`}),r=async(n,a)=>{try{let i=await fetch(`${t}${S}${n}`,{method:a.method,headers:await o(),...a.body===void 0?{}:{body:JSON.stringify(a.body)}});if(i.status===409){let d=await i.json().catch(()=>({}));throw new v(d.message??"Someone else saved this first.")}if(!i.ok){let d=await i.text().catch(()=>""),u=`${a.method} ${n} \u2192 ${String(i.status)}`;try{let y=JSON.parse(d);y.message&&(u=y.message)}catch{u=d?`${u}: ${d}`:u}throw T(new Error(u))}return await i.json()}catch(i){throw T(i)}},l=n=>`/tables/${encodeURIComponent(n)}`;return{listTables:async()=>(await b(`${t}${S}/tables`,await o())).tables,listRows:async(n,a)=>await b(`${t}${S}${l(n)}/rows?limit=${String(a??100)}`,await o()),insertRow:async(n,a)=>{let{rowIds:i}=await r(`${l(n)}/rows`,{method:"POST",body:{rows:[a]}}),d=i[0];if(!d)throw T(new Error("The row was not created."));return d},patchRow:async(n,a,i)=>(await r(`${l(n)}/rows/${encodeURIComponent(a)}`,{method:"PATCH",body:i})).updated,deleteRow:async(n,a)=>(await r(`/${encodeURIComponent(n)}/${encodeURIComponent(a)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await b(`${t}${S}/tables/files/rows?limit=200`,await o())).rows.map(a=>({id:a.rowId,filename:String(a.data.filename??""),source:String(a.data.source??"client"),campaign:String(a.data.campaign??""),size:typeof a.data.size=="number"?a.data.size:0,createdAt:a.createdAt})),uploadFile:async(n,a)=>{let i=new Uint8Array(await n.arrayBuffer());return await r("/files",{method:"POST",body:{filename:n.name,mime:n.type||"application/octet-stream",data:ze(i),...a===void 0?{}:{message:a}}})},fileLink:async n=>await b(`${t}${S}/files/${encodeURIComponent(n)}/url`,await o()),deleteFile:async n=>(await r(`/files/${encodeURIComponent(n)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await b(`${t}${S}/documents`,await o())).documents,readDocument:async n=>(await b(`${t}${S}/documents/${encodeURIComponent(n)}`,await o())).document,saveDocument:async(n,a)=>await r(`/documents/${encodeURIComponent(n)}`,{method:"PATCH",body:a})}};import{useCallback as Ve,useEffect as le,useRef as qe,useState as I}from"react";var de="greeting";function ue(e,t){if(e.some(r=>r.id===t.id))return e;let s=e.filter(r=>r.id!==de);return[...t.author==="client"?s.filter(r=>!(r.pending&&r.author==="client"&&r.text===t.text)):s,t]}var Xe=(e,t)=>{let[s,o]=I([]),[r,l]=I(""),[n,a]=I(!1),[i,d]=I(null),u=qe(0),y=t?.pollMs??2e3;le(()=>{let p=!0;return e.getInfo().then(m=>{p&&m.greeting&&o(g=>g.length===0?[{id:de,cursor:"",author:"agent",text:m.greeting}]:g)}).catch(()=>{}),()=>{p=!1}},[e]),le(()=>e.subscribe?.({onMessage:p=>o(m=>ue(m,p)),onError:p=>d(p.error),onHealthy:()=>d(null)},{intervalMs:y}),[e,y]);let c=Ve(()=>{let p=r.trim();if(!p||n)return;l(""),d(null),a(!0),u.current+=1;let m={id:`pending-${u.current}`,cursor:"",author:"client",text:p,pending:!0};o(g=>[...g,m]),e.sendMessage(p).then(()=>a(!1)).catch(g=>{d(g instanceof Error?g.message:"send_failed"),a(!1)})},[r,n,e]);return{messages:s,input:r,setInput:l,send:c,sending:n,error:i}};export{He as Chat,F as GRID_MAX_COLS,L as GRID_MAX_ROWS,xe as HolaProvider,v as PortalConflict,N as bandOfKind,Q as bandOfType,fe as createApiTransport,Ie as createHolaClient,Je as createPortalData,_ as createWidgetTransport,q as deriveFields,Z as footprintOf,B as footprintWith,Y as inferSpec,ee as layoutSegments,ue as mergeMessage,ie as parseDashboardSpec,se as renderModel,M as textDeltaOf,E as thinkingDeltaOf,A as toolEventOf,$ as useArtifactUrl,O as useChat,D as useHolaClient,Xe as useThread};
8
+ `)}},u=async()=>{let d=await a.read();if(!d.done)return i+=n.decode(d.value,{stream:!0}),l(),u()};await u()};var De=/\/+$/,C="/api/v1/end-user",Se=e=>{let t=e.baseUrl.replace(De,""),o=()=>typeof e.token=="function"?e.token():e.token,s=n=>e.project?`${n}project=${encodeURIComponent(e.project)}`:"",r=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),a=async n=>{let i=await fetch(`${t}${C}/chat${s("?")}`,{method:"POST",headers:await r(),body:JSON.stringify({message:n})});if(!i.ok)throw new Error(`hola: message failed (${i.status})`);return{reply:(await i.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>b(`${t}${C}/chat/info${s("?")}`,await r()),sendMessage:a,streamMessage:async(n,i)=>{try{let l=await a(n);i.onText?.(l.reply),i.onComplete?.(l)}catch(l){i.onError?.(v(l))}},subscribe:(n,i)=>{let l=i?.since??"0",u=!1,d,y=i?.intervalMs??3e3,c=async()=>{try{let f=await b(`${t}${C}/chat/thread?since=${encodeURIComponent(l)}${s("&")}`,await r());for(let m of f.messages)n.onMessage(m);l=f.cursor,n.onHealthy?.()}catch(f){n.onError?.(v(f))}u||(d=setTimeout(c,y))},p=()=>{u=!0,d&&clearTimeout(d)};return i?.signal?.addEventListener("abort",p),d=setTimeout(c,0),p},requestHuman:async()=>{await fetch(`${t}${C}/chat/request-human${s("?")}`,{method:"POST",headers:await r(),body:"{}"})}}};import{useEffect as Ce,useState as Re}from"react";var E=(e,t)=>{let[o,s]=Re("");return Ce(()=>{if(!e){s("");return}let r=Uint8Array.from(atob(e),n=>n.charCodeAt(0)),a=URL.createObjectURL(new Blob([r],{type:t}));return s(a),()=>URL.revokeObjectURL(a)},[e,t]),o};import{useEffect as Ee,useRef as $e}from"react";import{createContext as Pe,useContext as Ie}from"react";import{jsx as Me}from"react/jsx-runtime";var X=Pe(null),He=({client:e,children:t})=>Me(X.Provider,{value:e,children:t}),$=()=>{let e=Ie(X);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};import{useCallback as K,useEffect as We,useRef as Ae,useState as R}from"react";var O=e=>{let[t,o]=R([]),[s,r]=R(""),[a,n]=R(!1),[i,l]=R(null),u=Ae(0),d=K(()=>{let c=u.current;return u.current+=1,c},[]);We(()=>{let c=!0;return e.getInfo().then(p=>{c&&p.greeting&&o([{id:d(),role:"assistant",text:p.greeting}])}).catch(()=>{}),()=>{c=!1}},[e,d]);let y=K(()=>{let c=s.trim();if(!c||a)return;r(""),l(null),n(!0);let p=d(),f=d();o(g=>[...g,{id:p,role:"user",text:c},{id:f,role:"assistant",text:"",streaming:!0}]);let m=g=>{o(h=>h.map(H=>H.id===f?g(H):H))};e.streamMessage(c,{onText:g=>m(h=>({...h,text:h.text+g})),onComplete:g=>{m(h=>({...h,text:g.reply||h.text,artifacts:g.artifacts,streaming:!1})),n(!1)},onError:g=>{m(h=>({...h,streaming:!1})),l(g.error),n(!1)}}).catch(g=>{m(h=>({...h,streaming:!1})),l(g instanceof Error?g.message:"stream_failed"),n(!1)})},[s,a,e,d]);return{messages:t,input:s,setInput:r,send:y,sending:a,error:i}};import{jsx as k,jsxs as _}from"react/jsx-runtime";var w={root:{display:"flex",flexDirection:"column",height:"100%",fontFamily:"system-ui, -apple-system, sans-serif",fontSize:14,color:"#111827"},log:{flex:1,overflowY:"auto",padding:12,display:"flex",flexDirection:"column",gap:8},user:{alignSelf:"flex-end",background:"#111827",color:"#ffffff",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},assistant:{alignSelf:"flex-start",background:"#f1f1f4",color:"#111827",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},artifacts:{display:"flex",flexDirection:"column",gap:6,marginTop:6},image:{maxHeight:220,borderRadius:8,border:"1px solid #e5e7eb"},link:{color:"#2563eb",textDecoration:"underline",wordBreak:"break-all"},error:{color:"#b91c1c",padding:"4px 12px",fontSize:13},form:{display:"flex",gap:8,borderTop:"1px solid #e5e7eb",padding:8},input:{flex:1,border:"1px solid #d1d5db",borderRadius:8,padding:"8px 10px",fontSize:14,outline:"none"},button:{border:"none",background:"#111827",color:"#ffffff",borderRadius:8,padding:"8px 14px",fontSize:14,cursor:"pointer"}},Oe=({artifact:e})=>{let t=E(e.dataBase64??"",e.mimeType),o=e.url??t;return o?e.mimeType.startsWith("image/")?k("a",{href:o,rel:"noopener noreferrer",target:"_blank",children:k("img",{alt:e.filename,src:o,style:w.image})}):k("a",{download:e.filename,href:o,style:w.link,children:e.filename}):null},_e=()=>{let e=$(),{messages:t,input:o,setInput:s,send:r,sending:a,error:n}=O(e),i=$e(null);Ee(()=>{let u=i.current;u&&(u.scrollTop=u.scrollHeight)},[t]);let l=u=>{u.preventDefault(),r()};return _("div",{style:w.root,children:[k("div",{ref:i,style:w.log,children:t.map(u=>_("div",{style:u.role==="user"?w.user:w.assistant,children:[u.text||(u.streaming?"\u2026":""),u.artifacts&&u.artifacts.length>0?k("div",{style:w.artifacts,children:u.artifacts.map(d=>k(Oe,{artifact:d},d.filename))}):null]},u.id))}),n?k("div",{style:w.error,children:n}):null,_("form",{onSubmit:l,style:w.form,children:[k("input",{"aria-label":"Message",onChange:u=>s(u.target.value),placeholder:"Type a message\u2026",style:w.input,value:o}),k("button",{disabled:a||o.trim().length===0,style:w.button,type:"submit",children:"Send"})]})]})};var Ue=/\/+$/,U=e=>{let t=e.sessionId,o=e.baseUrl.replace(Ue,""),s=n=>`${o}/endpoint/${encodeURIComponent(e.token)}${n}`,r={"content-type":"application/json"},a=(n,i)=>({url:s(n),headers:r,body:JSON.stringify({message:i,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>b(s("/config"),{}),sendMessage:async n=>{let i=await J(a("/message",n));return t=i.sessionId,i},streamMessage:(n,i,l)=>q(a("/message/stream",n),i,u=>{t=u},l),subscribe:(n,i)=>{let l=i?.since??"0",u=!1,d,y=i?.intervalMs??3e3,c=async()=>{let f=t;if(f)try{let m=await b(s(`/messages?session=${encodeURIComponent(f)}&since=${encodeURIComponent(l)}`),{});for(let g of m.messages)n.onMessage(g);l=m.cursor,n.onHealthy?.()}catch(m){n.onError?.(v(m))}u||(d=setTimeout(c,y))},p=()=>{u=!0,d&&clearTimeout(d)};return i?.signal?.addEventListener("abort",p),d=setTimeout(c,0),p},requestHuman:async()=>{t&&await fetch(s("/request-human"),{method:"POST",headers:r,body:JSON.stringify({sessionId:t})})}}};var Fe=e=>"transport"in e?e.transport:U(e);var Le=/^https?:\/\//i,Ne=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Be=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function je(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(Le.test(e))return"url";if(Ne.test(e))return"date"}return"text"}function Y(e){let t=[],o=new Map;for(let s of e)for(let[r,a]of Object.entries(s.data??{})){if(a==null)continue;let n=o.get(r);n||(n=new Map,o.set(r,n),t.push(r));let i=je(a);n.set(i,(n.get(i)??0)+1)}return t.map(s=>{let r=o.get(s)??new Map,a="text",n=-1;for(let[i,l]of r)l>n&&(n=l,a=i);return{key:s,label:Be(s),type:a}})}var Ve=e=>typeof e=="number"?e:Number(e)||0,Q=e=>/rate|position|rank|score|percent|avg/i.test(e),Ge=/posted|published|sent|completed|shipped|launched|_at|date/i,ze=new Set(["service","order","end_user_id"]);function Z(e,t){let o=e.filter(l=>!ze.has(l.key)),s=o.filter(l=>l.type==="number").slice(0,3),r=o.find(l=>l.key==="status")??o.find(l=>l.type==="select"),a=o.find(l=>l.type==="date"&&Ge.test(l.key))??o.find(l=>l.type==="date"),n=o.filter(l=>l.type==="number"&&!Q(l.key)).map(l=>({field:l,total:t.reduce((u,d)=>u+Ve(d.data[l.key]),0)})).sort((l,u)=>u.total-l.total).find(l=>l.total>0)?.field??null,i=[{type:"stat",label:"Items",agg:"count"}];for(let l of s){let u=Q(l.key);i.push({type:"stat",metric:l.key,agg:u?"avg":"sum",label:u?`Avg ${l.label.toLowerCase()}`:l.label})}return a&&i.push({type:"line",x:a.key,y:n?.key,agg:"sum",title:n?`${n.label} by day`:"Items by day"}),r&&i.push({type:"donut",groupBy:r.key,title:r.label}),i.push({type:"table",columns:o.map(l=>l.key)}),{version:1,widgets:i}}var ee={stat:{span:1,h:1},chart:{span:2,h:2},block:{span:0,h:0}},F=6,L=4,Je=e=>Math.max(1,Math.min(F,Math.round(e))),qe=e=>Math.max(1,Math.min(L,Math.round(e)));function N(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function te(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function ne(e){return ee[e]}function B(e,t,o){let s=ee[e];return{span:t===void 0?s.span:Je(t),h:o===void 0?s.h:qe(o)}}function re(e){let t=[],o=null;for(let s of e){let r=N(s.kind);if(r==="block"){t.push({kind:"block",widget:s}),o=null;continue}let a=B(r,s.w,s.h),n={widget:s,span:a.span,h:a.h,band:r};o?o.cells.push(n):(o={kind:"grid",cells:[n]},t.push(o))}return t}var oe=new Set(["service","order","end_user_id"]),se=e=>typeof e=="number"?e:Number(e)||0,ie=e=>e==null?"":String(e);function ae(e,t){if(e==="count")return t.length;if(t.length===0)return 0;if(e==="last")return t[t.length-1]??0;if(e==="min")return Math.min(...t);if(e==="max")return Math.max(...t);let o=t.reduce((s,r)=>s+r,0);return e==="avg"?Math.round(o/t.length):o}function Xe(e,t,o,s){let r=new Map;for(let a of e){let n=new Date(ie(a.data[t]));if(Number.isNaN(n.getTime()))continue;let i=n.toISOString().slice(0,10),l=r.get(i)??[];l.push(o?se(a.data[o]):1),r.set(i,l)}return[...r.entries()].sort((a,n)=>a[0]<n[0]?-1:1).map(([a,n])=>({label:new Date(`${a}T00:00:00`).toLocaleDateString(void 0,{month:"short",day:"numeric"}),value:o?ae(s,n):n.length}))}function Ke(e,t){let o=new Map;for(let s of e){let r=ie(s.data[t]).trim();r&&o.set(r,(o.get(r)??0)+1)}return[...o.entries()].sort((s,r)=>r[1]-s[1]).map(([s,r])=>({label:s,value:r}))}function Ye(e,t,o,s){switch(e.type){case"stat":{let r=e.metric?t.get(e.metric):void 0;if(e.metric&&!r)return null;if(!r)return{kind:"stat",label:e.label??"Items",value:s.length};let a=s.map(n=>se(n.data[r.key]));return{kind:"stat",label:e.label??r.label,value:ae(e.agg??"sum",a)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let r=Xe(s,e.x,e.y,e.agg??"sum");return r.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:r}}case"donut":{if(!t.has(e.groupBy))return null;let r=Ke(s,e.groupBy);return r.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:r}}case"table":{let r=e.columns?e.columns.map(a=>t.get(a)).filter(a=>a!==void 0&&!oe.has(a.key)):o;return r.length===0?null:{kind:"table",title:e.title,columns:r,rows:s}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function le(e,t,o){let s=t.filter(n=>!oe.has(n.key)),r=new Map(t.map(n=>[n.key,n])),a=[];for(let n of e.widgets){let i=Ye(n,r,s,o);i&&a.push({...i,w:n.w,h:n.h})}return a}var Qe=new Set(["sum","avg","count","min","max","last"]),ue=e=>typeof e=="string"&&Qe.has(e)?e:void 0,x=e=>typeof e=="string"&&e!==""?e:void 0,D=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,S=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0;function Ze(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",label:x(t.label),metric:x(t.metric),agg:ue(t.agg),w:D(t.w),h:S(t.h)};case"line":case"bar":{let o=x(t.x);return o?{type:t.type,title:x(t.title),x:o,y:x(t.y),agg:ue(t.agg),w:D(t.w),h:S(t.h)}:null}case"donut":{let o=x(t.groupBy);return o?{type:"donut",title:x(t.title),groupBy:o,w:D(t.w),h:S(t.h)}:null}case"table":{let o=Array.isArray(t.columns)?t.columns.filter(s=>typeof s=="string"):void 0;return{type:"table",title:x(t.title),columns:o,w:D(t.w),h:S(t.h)}}case"text":{let o=x(t.body);return o?{type:"text",title:x(t.title),body:o,w:D(t.w),h:S(t.h)}:null}default:return null}}function de(e){let t=e;if(typeof e=="string"){if(e.trim()==="")return null;try{t=JSON.parse(e)}catch{return null}}if(typeof t!="object"||t===null)return null;let o=t.widgets;if(!Array.isArray(o))return null;let s=o.map(Ze).filter(a=>a!==null);if(s.length===0)return null;let r=t.version;return{version:typeof r=="number"?r:1,title:x(t.title),widgets:s}}function j(e){if(typeof e=="string")return e?{kind:"file",value:e}:null;if(e&&typeof e=="object"){let t=e,o=typeof t.value=="string"?t.value:"",s=t.kind==="link"||t.kind==="text"||t.kind==="table"?t.kind:"file",r=typeof t.v=="number"&&t.v>=1?Math.floor(t.v):void 0;return o?{kind:s,value:o,...r?{v:r}:{}}:null}return null}function V(e){let t=new Map;for(let o of e){let s=o.v??1,r=t.get(s)??[];r.push(o),t.set(s,r)}return[...t.entries()].sort(([o],[s])=>o-s).map(([o,s])=>({v:o,items:s}))}function pe(e){let t=e.files;if(typeof t=="string"&&t.trim()!=="")try{let s=JSON.parse(t);if(Array.isArray(s))return s.map(j).filter(r=>r!==null)}catch{}let o=String(e.file??"");return o?[{kind:"file",value:o}]:[]}function ce(e,t,o){let r=(V(e).find(n=>n.v===t)?.items??[]).filter(n=>n.kind==="file").map(n=>n.value),a=r.map(n=>o.get(n)??"");return r.length===0||a.some(n=>n==="")?"awaiting":a.some(n=>n==="revise")?"revise":"accepted"}function me(e){return Number(e.published_version)||0}function G(e){return e==="number"||e==="date"||e==="boolean"||e==="select"||e==="url"?e:e==="link"?"url":e==="checkbox"?"boolean":"text"}function fe(e){try{let t=JSON.parse(e);if(Array.isArray(t.columns)&&Array.isArray(t.rows)&&t.columns.length){let o=t.columns.map((a,n)=>({key:typeof a.key=="string"&&a.key?a.key:typeof a.id=="string"&&a.id?a.id:`column_${n+1}`,label:typeof a.label=="string"?a.label:"",type:G(a.type)})),s=t.rows.map((a,n)=>({id:typeof a.id=="string"&&a.id?a.id:`row_${n}`,cells:a.cells&&typeof a.cells=="object"?a.cells:{}})),r=typeof t.name=="string"?t.name:void 0;return{columns:o,rows:s,...r?{name:r}:{}}}}catch{}return null}function ge(e){return e==null?"":String(e)}function ye(e){return e===!0||e==="true"||e==="1"||e==="yes"||e==="\u2713"}function be(e){let t=new Date(`${e}T00:00:00`);return Number.isNaN(t.getTime())?e:t.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})}var et=/\/+$/,T="/api/v1/end-user",P=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function tt(e){let t="";for(let s=0;s<e.length;s+=32768)t+=String.fromCharCode(...e.subarray(s,s+32768));return btoa(t)}var nt=e=>{let t=e.baseUrl.replace(et,""),o=()=>typeof e.token=="function"?e.token():e.token,s=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),r=async(n,i)=>{try{let l=await fetch(`${t}${T}${n}`,{method:i.method,headers:await s(),...i.body===void 0?{}:{body:JSON.stringify(i.body)}});if(l.status===409){let u=await l.json().catch(()=>({}));throw new P(u.message??"Someone else saved this first.")}if(!l.ok){let u=await l.text().catch(()=>""),d=`${i.method} ${n} \u2192 ${String(l.status)}`;try{let y=JSON.parse(u);y.message&&(d=y.message)}catch{d=u?`${d}: ${u}`:d}throw v(new Error(d))}return await l.json()}catch(l){throw v(l)}},a=n=>`/tables/${encodeURIComponent(n)}`;return{listTables:async()=>(await b(`${t}${T}/tables`,await s())).tables,listRows:async(n,i)=>await b(`${t}${T}${a(n)}/rows?limit=${String(i??100)}`,await s()),insertRow:async(n,i)=>{let{rowIds:l}=await r(`${a(n)}/rows`,{method:"POST",body:{rows:[i]}}),u=l[0];if(!u)throw v(new Error("The row was not created."));return u},patchRow:async(n,i,l)=>(await r(`${a(n)}/rows/${encodeURIComponent(i)}`,{method:"PATCH",body:l})).updated,deleteRow:async(n,i)=>(await r(`/${encodeURIComponent(n)}/${encodeURIComponent(i)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await b(`${t}${T}/tables/files/rows?limit=200`,await s())).rows.map(i=>({id:i.rowId,filename:String(i.data.filename??""),source:String(i.data.source??"client"),campaign:String(i.data.campaign??""),size:typeof i.data.size=="number"?i.data.size:0,createdAt:i.createdAt})),uploadFile:async(n,i)=>{let l=new Uint8Array(await n.arrayBuffer());return await r("/files",{method:"POST",body:{filename:n.name,mime:n.type||"application/octet-stream",data:tt(l),...i===void 0?{}:{message:i}}})},fileLink:async n=>await b(`${t}${T}/files/${encodeURIComponent(n)}/url`,await s()),deleteFile:async n=>(await r(`/files/${encodeURIComponent(n)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await b(`${t}${T}/documents`,await s())).documents,readDocument:async n=>(await b(`${t}${T}/documents/${encodeURIComponent(n)}`,await s())).document,saveDocument:async(n,i)=>await r(`/documents/${encodeURIComponent(n)}`,{method:"PATCH",body:i})}};import{useCallback as rt,useEffect as he,useRef as ot,useState as I}from"react";var we="greeting";function xe(e,t){if(e.some(r=>r.id===t.id))return e;let o=e.filter(r=>r.id!==we);return[...t.author==="client"?o.filter(r=>!(r.pending&&r.author==="client"&&r.text===t.text)):o,t]}var st=(e,t)=>{let[o,s]=I([]),[r,a]=I(""),[n,i]=I(!1),[l,u]=I(null),d=ot(0),y=t?.pollMs??2e3;he(()=>{let p=!0;return e.getInfo().then(f=>{p&&f.greeting&&s(m=>m.length===0?[{id:we,cursor:"",author:"agent",text:f.greeting}]:m)}).catch(()=>{}),()=>{p=!1}},[e]),he(()=>e.subscribe?.({onMessage:p=>s(f=>xe(f,p)),onError:p=>u(p.error),onHealthy:()=>u(null)},{intervalMs:y}),[e,y]);let c=rt(()=>{let p=r.trim();if(!p||n)return;a(""),u(null),i(!0),d.current+=1;let f={id:`pending-${d.current}`,cursor:"",author:"client",text:p,pending:!0};s(m=>[...m,f]),e.sendMessage(p).then(()=>i(!1)).catch(m=>{u(m instanceof Error?m.message:"send_failed"),i(!1)})},[r,n,e]);return{messages:o,input:r,setInput:a,send:c,sending:n,error:l}};export{_e as Chat,F as GRID_MAX_COLS,L as GRID_MAX_ROWS,He as HolaProvider,P as PortalConflict,N as bandOfKind,te as bandOfType,Se as createApiTransport,Fe as createHolaClient,nt as createPortalData,U as createWidgetTransport,ge as deliverableCellText,ce as deliverableStatus,Y as deriveFields,ne as footprintOf,B as footprintWith,be as formatDeliverableDate,V as groupDeliverableVersions,Z as inferSpec,ye as isDeliverableChecked,re as layoutSegments,xe as mergeMessage,G as normalizeDeliverableColType,j as normalizeDeliverableItem,de as parseDashboardSpec,pe as parseDeliverableItems,fe as parseDeliverableTable,me as publishedVersionOf,le as renderModel,M as textDeltaOf,W as thinkingDeltaOf,A as toolEventOf,E as useArtifactUrl,O as useChat,$ as useHolaClient,st as useThread};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holaboss/client",
3
- "version": "0.2.0-beta.8",
3
+ "version": "0.2.0-beta.9",
4
4
  "description": "Injectable client SDK for embedding a Holaboss AI employee (chat + configurable dashboards today; artifacts next) into your own web app.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",