@holaboss/client 0.2.0-beta.14 → 0.2.0-beta.16

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 K=Object.defineProperty;var _e=Object.getOwnPropertyDescriptor;var Le=Object.getOwnPropertyNames;var Ue=Object.prototype.hasOwnProperty;var Fe=(e,t)=>{for(var o in t)K(e,o,{get:t[o],enumerable:!0})},Ne=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Le(t))!Ue.call(e,s)&&s!==o&&K(e,s,{get:()=>t[s],enumerable:!(r=_e(t,s))||r.enumerable});return e};var Ve=e=>Ne(K({},"__esModule",{value:!0}),e);var pt={};Fe(pt,{Chat:()=>De,GRID_COLS:()=>Z,GRID_MAX_COLS:()=>ee,GRID_MAX_ROWS:()=>te,HolaProvider:()=>ke,PortalConflict:()=>H,bandOfKind:()=>W,bandOfType:()=>ne,cellValue:()=>ge,createApiTransport:()=>ve,createHolaClient:()=>Ce,createPortalData:()=>Ee,createWidgetTransport:()=>j,deliverableCellText:()=>pe,deliverableStatus:()=>le,deriveFields:()=>Y,footprintOf:()=>re,footprintWith:()=>B,formatDeliverableDate:()=>ye,groupDeliverableVersions:()=>q,inferSpec:()=>Q,isDeliverableChecked:()=>ce,mergeMessage:()=>be,normalizeDeliverableColType:()=>X,normalizeDeliverableItem:()=>J,parseDashboardSpec:()=>ie,parseDeliverableItems:()=>ae,parseDeliverableTable:()=>de,parseTableResponses:()=>fe,placeWidgets:()=>z,publishedVersionOf:()=>ue,renderModel:()=>se,setResponse:()=>me,splitLayout:()=>oe,textDeltaOf:()=>E,thinkingDeltaOf:()=>$,toolEventOf:()=>O,useArtifactUrl:()=>U,useChat:()=>V,useHolaClient:()=>N,useThread:()=>Oe});module.exports=Ve(pt);var he=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="message_update"?t.assistantMessageEvent??null:null},E=e=>{let t=he(e);return t?.type==="text_delta"&&typeof t.delta=="string"?t.delta:null},$=e=>{let t=he(e);return t?.type==="thinking_delta"&&typeof t.delta=="string"?t.delta:null},O=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 Ge=/^ /,C=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"}},je=e=>{let t="message",o=[];for(let r of e.split(`
3
- `))r.startsWith(":")||(r.startsWith("event:")?t=r.slice(6).trim():r.startsWith("data:")&&o.push(r.slice(5).replace(Ge,"")));return o.length>0?{event:t,data:o.join(`
4
- `)}:null},Be=(e,t,o)=>{let r;try{r=JSON.parse(e.data)}catch{return}if(e.event==="session"){let s=r.sessionId;s&&(o(s),t.onSession?.(s));return}if(e.event==="turn_event"){t.onEvent?.(r);let s=E(r);s&&t.onText?.(s);let a=$(r);a&&t.onThinking?.(a);let n=O(r);n&&t.onTool?.(n);return}if(e.event==="chat_completed"){let s=r;o(s.sessionId),t.onComplete?.(s);return}e.event==="chat_error"&&t.onError?.(C(r))},v=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()},we=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()},xe=async(e,t,o,r)=>{let s=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body,signal:r});if(!(s.ok&&s.body)){t.onError?.({error:`stream_failed_${s.status}`});return}let a=s.body.getReader(),n=new TextDecoder,i="",l=()=>{let d=i.indexOf(`
2
+ var q=Object.defineProperty;var Ue=Object.getOwnPropertyDescriptor;var Fe=Object.getOwnPropertyNames;var Ne=Object.prototype.hasOwnProperty;var Ve=(e,t)=>{for(var r in t)q(e,r,{get:t[r],enumerable:!0})},je=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Fe(t))!Ne.call(e,i)&&i!==r&&q(e,i,{get:()=>t[i],enumerable:!(o=Ue(t,i))||o.enumerable});return e};var Ge=e=>je(q({},"__esModule",{value:!0}),e);var mt={};Ve(mt,{Chat:()=>Se,GRID_COLS:()=>ee,GRID_MAX_COLS:()=>te,GRID_MAX_ROWS:()=>ne,HolaProvider:()=>De,PortalConflict:()=>H,bandOfKind:()=>W,bandOfType:()=>re,cellValue:()=>fe,createApiTransport:()=>Re,createHolaClient:()=>Pe,createPortalData:()=>Oe,createWidgetTransport:()=>G,deliverableCellText:()=>ce,deliverableStatus:()=>ue,deriveFields:()=>Q,emptyTableResponses:()=>E,footprintOf:()=>oe,footprintWith:()=>B,formatDeliverableDate:()=>he,groupDeliverableVersions:()=>X,inferSpec:()=>Z,isDeliverableChecked:()=>me,mergeMessage:()=>we,normalizeDeliverableColType:()=>K,normalizeDeliverableItem:()=>J,parseDashboardSpec:()=>ae,parseDeliverableItems:()=>le,parseDeliverableTable:()=>pe,parseTableResponses:()=>ge,placeWidgets:()=>z,publishedVersionOf:()=>de,renderModel:()=>ie,setResponse:()=>be,setTableReview:()=>ye,splitLayout:()=>se,textDeltaOf:()=>$,thinkingDeltaOf:()=>O,toolEventOf:()=>_,useArtifactUrl:()=>U,useChat:()=>V,useHolaClient:()=>N,useThread:()=>Le});module.exports=Ge(mt);var xe=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="message_update"?t.assistantMessageEvent??null:null},$=e=>{let t=xe(e);return t?.type==="text_delta"&&typeof t.delta=="string"?t.delta:null},O=e=>{let t=xe(e);return t?.type==="thinking_delta"&&typeof t.delta=="string"?t.delta:null},_=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 Be=/^ /,C=e=>{if(e&&typeof e=="object"){let t=e,r=typeof t.error=="string"?t.error:"request_failed";return typeof t.retryable=="boolean"?{error:r,retryable:t.retryable}:{error:r}}return{error:"request_failed"}},ze=e=>{let t="message",r=[];for(let o of e.split(`
3
+ `))o.startsWith(":")||(o.startsWith("event:")?t=o.slice(6).trim():o.startsWith("data:")&&r.push(o.slice(5).replace(Be,"")));return r.length>0?{event:t,data:r.join(`
4
+ `)}:null},Je=(e,t,r)=>{let o;try{o=JSON.parse(e.data)}catch{return}if(e.event==="session"){let i=o.sessionId;i&&(r(i),t.onSession?.(i));return}if(e.event==="turn_event"){t.onEvent?.(o);let i=$(o);i&&t.onText?.(i);let a=O(o);a&&t.onThinking?.(a);let n=_(o);n&&t.onTool?.(n);return}if(e.event==="chat_completed"){let i=o;r(i.sessionId),t.onComplete?.(i);return}e.event==="chat_error"&&t.onError?.(C(o))},v=async(e,t)=>{let r=await fetch(e,{headers:t});if(!r.ok)throw new Error(`hola: request failed (${r.status})`);return await r.json()},ve=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()},Te=async(e,t,r,o)=>{let i=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body,signal:o});if(!(i.ok&&i.body)){t.onError?.({error:`stream_failed_${i.status}`});return}let a=i.body.getReader(),n=new TextDecoder,s="",l=()=>{let d=s.indexOf(`
5
5
 
6
- `);for(;d!==-1;){let f=i.slice(0,d);i=i.slice(d+2);let g=je(f);g&&Be(g,t,o),d=i.indexOf(`
6
+ `);for(;d!==-1;){let m=s.slice(0,d);s=s.slice(d+2);let g=ze(m);g&&Je(g,t,r),d=s.indexOf(`
7
7
 
8
- `)}},u=async()=>{let d=await a.read();if(!d.done)return i+=n.decode(d.value,{stream:!0}),l(),u()};await u()};var ze=/\/+$/,_="/api/v1/end-user",ve=e=>{let t=e.baseUrl.replace(ze,""),o=()=>typeof e.token=="function"?e.token():e.token,r=n=>e.project?`${n}project=${encodeURIComponent(e.project)}`:"",s=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),a=async n=>{let i=await fetch(`${t}${_}/chat${r("?")}`,{method:"POST",headers:await s(),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()=>v(`${t}${_}/chat/info${r("?")}`,await s()),sendMessage:a,streamMessage:async(n,i)=>{try{let l=await a(n);i.onText?.(l.reply),i.onComplete?.(l)}catch(l){i.onError?.(C(l))}},subscribe:(n,i)=>{let l=i?.since??"0",u=!1,d,f=i?.intervalMs??3e3,g=typeof document<"u",p=()=>g&&document.visibilityState==="hidden",y=!1,h=()=>{if(!u){if(p()){y=!0;return}d=setTimeout(m,f)}},m=async()=>{try{let b=await v(`${t}${_}/chat/thread?since=${encodeURIComponent(l)}${r("&")}`,await s());for(let P of b.messages)n.onMessage(P);l=b.cursor,n.onHealthy?.()}catch(b){n.onError?.(C(b))}h()},D=()=>{u||!y||p()||(y=!1,d&&clearTimeout(d),d=setTimeout(m,0))};g&&document.addEventListener("visibilitychange",D);let c=()=>{u=!0,d&&clearTimeout(d),g&&document.removeEventListener("visibilitychange",D)};return i?.signal?.addEventListener("abort",c),d=setTimeout(m,0),c},requestHuman:async()=>{await fetch(`${t}${_}/chat/request-human${r("?")}`,{method:"POST",headers:await s(),body:"{}"})}}};var L=require("react"),U=(e,t)=>{let[o,r]=(0,L.useState)("");return(0,L.useEffect)(()=>{if(!e){r("");return}let s=Uint8Array.from(atob(e),n=>n.charCodeAt(0)),a=URL.createObjectURL(new Blob([s],{type:t}));return r(a),()=>URL.revokeObjectURL(a)},[e,t]),o};var G=require("react");var F=require("react"),Re=require("react/jsx-runtime"),Te=(0,F.createContext)(null),ke=({client:e,children:t})=>(0,Re.jsx)(Te.Provider,{value:e,children:t}),N=()=>{let e=(0,F.useContext)(Te);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};var w=require("react"),V=e=>{let[t,o]=(0,w.useState)([]),[r,s]=(0,w.useState)(""),[a,n]=(0,w.useState)(!1),[i,l]=(0,w.useState)(null),u=(0,w.useRef)(0),d=(0,w.useRef)(null);(0,w.useEffect)(()=>()=>d.current?.abort(),[]);let f=(0,w.useCallback)(()=>{let p=u.current;return u.current+=1,p},[]);(0,w.useEffect)(()=>{let p=!0;return e.getInfo().then(y=>{p&&y.greeting&&o([{id:f(),role:"assistant",text:y.greeting}])}).catch(()=>{}),()=>{p=!1}},[e,f]);let g=(0,w.useCallback)(()=>{let p=r.trim();if(!p||a)return;s(""),l(null),n(!0);let y=f(),h=f();o(c=>[...c,{id:y,role:"user",text:p},{id:h,role:"assistant",text:"",streaming:!0}]);let m=c=>{o(b=>b.map(P=>P.id===h?c(P):P))},D=new AbortController;d.current=D,e.streamMessage(p,{onText:c=>m(b=>({...b,text:b.text+c})),onComplete:c=>{m(b=>({...b,text:c.reply||b.text,artifacts:c.artifacts,streaming:!1})),n(!1)},onError:c=>{m(b=>({...b,streaming:!1})),l(c.error),n(!1)}},D.signal).catch(c=>{m(b=>({...b,streaming:!1})),l(c instanceof Error?c.message:"stream_failed"),n(!1)}).finally(()=>{n(!1),m(c=>c.streaming?{...c,streaming:!1}:c)})},[r,a,e,f]);return{messages:t,input:r,setInput:s,send:g,sending:a,error:i}};var x=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"}},Je=({artifact:e})=>{let t=U(e.dataBase64??"",e.mimeType),o=e.url??t;return o?e.mimeType.startsWith("image/")?(0,x.jsx)("a",{href:o,rel:"noopener noreferrer",target:"_blank",children:(0,x.jsx)("img",{alt:e.filename,src:o,style:k.image})}):(0,x.jsx)("a",{download:e.filename,href:o,style:k.link,children:e.filename}):null},De=()=>{let e=N(),{messages:t,input:o,setInput:r,send:s,sending:a,error:n}=V(e),i=(0,G.useRef)(null);(0,G.useEffect)(()=>{let u=i.current;u&&(u.scrollTop=u.scrollHeight)},[t]);let l=u=>{u.preventDefault(),s()};return(0,x.jsxs)("div",{style:k.root,children:[(0,x.jsx)("div",{ref:i,style:k.log,children:t.map(u=>(0,x.jsxs)("div",{style:u.role==="user"?k.user:k.assistant,children:[u.text||(u.streaming?"\u2026":""),u.artifacts&&u.artifacts.length>0?(0,x.jsx)("div",{style:k.artifacts,children:u.artifacts.map(d=>(0,x.jsx)(Je,{artifact:d},d.filename))}):null]},u.id))}),n?(0,x.jsx)("div",{style:k.error,children:n}):null,(0,x.jsxs)("form",{onSubmit:l,style:k.form,children:[(0,x.jsx)("input",{"aria-label":"Message",onChange:u=>r(u.target.value),placeholder:"Type a message\u2026",style:k.input,value:o}),(0,x.jsx)("button",{disabled:a||o.trim().length===0,style:k.button,type:"submit",children:"Send"})]})]})};var qe=/\/+$/,j=e=>{let t=e.sessionId,o=e.baseUrl.replace(qe,""),r=n=>`${o}/endpoint/${encodeURIComponent(e.token)}${n}`,s={"content-type":"application/json"},a=(n,i)=>({url:r(n),headers:s,body:JSON.stringify({message:i,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>v(r("/config"),{}),sendMessage:async n=>{let i=await we(a("/message",n));return t=i.sessionId,i},streamMessage:(n,i,l)=>xe(a("/message/stream",n),i,u=>{t=u},l),subscribe:(n,i)=>{let l=i?.since??"0",u=!1,d,f=i?.intervalMs??3e3,g=async()=>{let y=t;if(y)try{let h=await v(r(`/messages?session=${encodeURIComponent(y)}&since=${encodeURIComponent(l)}`),{});for(let m of h.messages)n.onMessage(m);l=h.cursor,n.onHealthy?.()}catch(h){n.onError?.(C(h))}u||(d=setTimeout(g,f))},p=()=>{u=!0,d&&clearTimeout(d)};return i?.signal?.addEventListener("abort",p),d=setTimeout(g,0),p},requestHuman:async()=>{t&&await fetch(r("/request-human"),{method:"POST",headers:s,body:JSON.stringify({sessionId:t})})}}};var Ce=e=>"transport"in e?e.transport:j(e);var Xe=/^https?:\/\//i,Ke=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Ye=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function Qe(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(Xe.test(e))return"url";if(Ke.test(e))return"date"}return"text"}function Y(e){let t=[],o=new Map;for(let r of e)for(let[s,a]of Object.entries(r.data??{})){if(a==null)continue;let n=o.get(s);n||(n=new Map,o.set(s,n),t.push(s));let i=Qe(a);n.set(i,(n.get(i)??0)+1)}return t.map(r=>{let s=o.get(r)??new Map,a="text",n=-1;for(let[i,l]of s)l>n&&(n=l,a=i);return{key:r,label:Ye(r),type:a}})}var Ze=e=>typeof e=="number"?e:Number(e)||0,Se=e=>/rate|position|rank|score|percent|avg/i.test(e),et=/posted|published|sent|completed|shipped|launched|_at/i,tt=new Set(["service","order","end_user_id"]);function Q(e,t){let o=e.filter(l=>!tt.has(l.key)),r=o.filter(l=>l.type==="number").slice(0,3),s=o.find(l=>l.key==="status")??o.find(l=>l.type==="select"),a=o.find(l=>l.type==="date"&&et.test(l.key))??o.find(l=>l.type==="date"),n=o.filter(l=>l.type==="number"&&!Se(l.key)).map(l=>({field:l,total:t.reduce((u,d)=>u+Ze(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 r){let u=Se(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"}),s&&i.push({type:"donut",groupBy:s.key,title:s.label}),i.push({type:"table",columns:o.map(l=>l.key)}),{version:1,widgets:i}}var Z=6,ee=6,te=4,Pe={stat:{w:1,h:1},chart:{w:2,h:2},block:{w:6,h:2}},nt=e=>Math.max(1,Math.min(6,Math.round(e))),rt=e=>Math.max(1,Math.min(4,Math.round(e)));function W(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function ne(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function re(e){return Pe[e]}function B(e,t,o){let r=Pe[e];return{w:t===void 0?r.w:nt(t),h:o===void 0?r.h:rt(o)}}function z(e){let t=[],o=[],r=(n,i,l,u)=>{if(n<0||n+l>6)return!1;for(let d=0;d<u;d+=1){let f=o[i+d];if(f){for(let g=0;g<l;g+=1)if(f[n+g])return!1}}return!0},s=(n,i,l,u)=>{for(let d=0;d<u;d+=1){let f=o[i+d]??[];for(let g=0;g<l;g+=1)f[n+g]=!0;o[i+d]=f}},a=(n,i)=>{for(let l=0;;l+=1)for(let u=0;u+n<=6;u+=1)if(r(u,l,n,i))return{gx:u,gy:l}};for(let n of e){let i=B(W(n.kind),n.w,n.h),u=n.gx!==void 0&&n.gy!==void 0&&r(n.gx,n.gy,i.w,i.h)&&n.gx!==void 0&&n.gy!==void 0?{gx:n.gx,gy:n.gy}:a(i.w,i.h);s(u.gx,u.gy,i.w,i.h),t.push({widget:n,gx:u.gx,gy:u.gy,w:i.w,h:i.h})}return t}function oe(e){let t=[],o=[];for(let r of e)W(r.kind)==="block"?o.push(r):t.push(r);return{tiles:z(t),blocks:o}}var Ie=new Set(["service","order","end_user_id"]),He=e=>typeof e=="number"?e:Number(e)||0,We=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((r,s)=>r+s,0);return e==="avg"?Math.round(o/t.length*100)/100:o}function ot(e,t,o,r){let s=new Map;for(let a of e){let n=new Date(We(a.data[t]));if(Number.isNaN(n.getTime()))continue;let i=n.toISOString().slice(0,10),l=s.get(i)??[];l.push(o?He(a.data[o]):1),s.set(i,l)}return[...s.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?Me(r,n):n.length}))}function st(e,t){let o=new Map;for(let r of e){let s=We(r.data[t]).trim();s&&o.set(s,(o.get(s)??0)+1)}return[...o.entries()].sort((r,s)=>s[1]-r[1]).map(([r,s])=>({label:r,value:s}))}function it(e,t,o,r){switch(e.type){case"stat":{let s=e.metric?t.get(e.metric):void 0;if(e.metric&&!s)return null;if(!s)return{kind:"stat",label:e.label??"Items",value:r.length};let a=r.map(n=>He(n.data[s.key]));return{kind:"stat",label:e.label??s.label,value:Me(e.agg??"sum",a)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let s=ot(r,e.x,e.y,e.agg??"sum");return s.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:s}}case"donut":{if(!t.has(e.groupBy))return null;let s=st(r,e.groupBy);return s.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:s}}case"table":{let s=e.columns?e.columns.map(a=>t.get(a)).filter(a=>a!==void 0&&!Ie.has(a.key)):o;return s.length===0?null:{kind:"table",title:e.title,columns:s,rows:r}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function se(e,t,o){let r=t.filter(n=>!Ie.has(n.key)),s=new Map(t.map(n=>[n.key,n])),a=[];for(let n of e.widgets){let i=it(n,s,r,o);i&&a.push({...i,w:n.w,h:n.h,gx:n.gx,gy:n.gy})}return a}var at=new Set(["sum","avg","count","min","max","last"]),Ae=e=>typeof e=="string"&&at.has(e)?e:void 0,R=e=>typeof e=="string"&&e!==""?e:void 0,M=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,A=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0,S=e=>typeof e=="number"&&e>=0?Math.round(e):void 0;function lt(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",label:R(t.label),metric:R(t.metric),agg:Ae(t.agg),w:M(t.w),h:A(t.h),gx:S(t.gx),gy:S(t.gy)};case"line":case"bar":{let o=R(t.x);return o?{type:t.type,title:R(t.title),x:o,y:R(t.y),agg:Ae(t.agg),w:M(t.w),h:A(t.h),gx:S(t.gx),gy:S(t.gy)}:null}case"donut":{let o=R(t.groupBy);return o?{type:"donut",title:R(t.title),groupBy:o,w:M(t.w),h:A(t.h),gx:S(t.gx),gy:S(t.gy)}:null}case"table":{let o=Array.isArray(t.columns)?t.columns.filter(r=>typeof r=="string"):void 0;return{type:"table",title:R(t.title),columns:o,w:M(t.w),h:A(t.h),gx:S(t.gx),gy:S(t.gy)}}case"text":{let o=R(t.body);return o?{type:"text",title:R(t.title),body:o,w:M(t.w),h:A(t.h),gx:S(t.gx),gy:S(t.gy)}: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 o=t.widgets;if(!Array.isArray(o))return null;let r=o.map(lt).filter(a=>a!==null);if(r.length===0)return null;let s=t.version;return{version:typeof s=="number"?s:1,title:R(t.title),widgets:r}}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:"",r=t.kind==="link"||t.kind==="text"||t.kind==="table"?t.kind:"file",s=typeof t.v=="number"&&t.v>=1?Math.floor(t.v):void 0;return o?{kind:r,value:o,...s?{v:s}:{}}:null}return null}function q(e){let t=new Map;for(let o of e){let r=o.v??1,s=t.get(r)??[];s.push(o),t.set(r,s)}return[...t.entries()].sort(([o],[r])=>o-r).map(([o,r])=>({v:o,items:r}))}function ae(e){let t=e.files;if(typeof t=="string"&&t.trim()!=="")try{let r=JSON.parse(t);if(Array.isArray(r))return r.map(J).filter(s=>s!==null)}catch{}let o=String(e.file??"");return o?[{kind:"file",value:o}]:[]}function le(e,t,o){let s=(q(e).find(n=>n.v===t)?.items??[]).filter(n=>n.kind==="file").map(n=>n.value),a=s.map(n=>o.get(n)??"");return s.length===0||a.some(n=>n==="")?"awaiting":a.some(n=>n==="revise")?"revise":"accepted"}function ue(e){return Number(e.published_version)||0}function X(e){return e==="number"||e==="date"||e==="boolean"||e==="select"||e==="url"?e:e==="link"?"url":e==="checkbox"?"boolean":"text"}function de(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:X(a.type),...a.clientEditable===!0?{clientEditable:!0}:{}})),r=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:{}})),s=typeof t.name=="string"?t.name:void 0;return{columns:o,rows:r,...s?{name:s}:{}}}}catch{}return null}function pe(e){return e==null?"":String(e)}function ce(e){return e===!0||e==="true"||e==="1"||e==="yes"||e==="\u2713"}function fe(e){if(typeof e!="string"||e.trim()==="")return{};try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}return{}}function ge(e,t,o){if(e.clientEditable){let r=o[t.id];if(r&&e.key in r)return r[e.key]}return t.cells[e.key]}function me(e,t,o,r){return{...e,[t]:{...e[t]??{},[o]:r}}}function ye(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 ut=/\/+$/,I="/api/v1/end-user",H=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function dt(e){let t="";for(let r=0;r<e.length;r+=32768)t+=String.fromCharCode(...e.subarray(r,r+32768));return btoa(t)}var Ee=e=>{let t=e.baseUrl.replace(ut,""),o=()=>typeof e.token=="function"?e.token():e.token,r=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),s=async(n,i)=>{try{let l=await fetch(`${t}${I}${n}`,{method:i.method,headers:await r(),...i.body===void 0?{}:{body:JSON.stringify(i.body)}});if(l.status===409){let u=await l.json().catch(()=>({}));throw new H(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 f=JSON.parse(u);f.message&&(d=f.message)}catch{d=u?`${d}: ${u}`:d}throw C({error:d})}return await l.json()}catch(l){throw l instanceof H?l:C(l)}},a=n=>`/tables/${encodeURIComponent(n)}`;return{listTables:async()=>(await v(`${t}${I}/tables`,await r())).tables,listRows:async(n,i)=>await v(`${t}${I}${a(n)}/rows?limit=${String(i??100)}`,await r()),insertRow:async(n,i)=>{let{rowIds:l}=await s(`${a(n)}/rows`,{method:"POST",body:{rows:[i]}}),u=l[0];if(!u)throw C(new Error("The row was not created."));return u},patchRow:async(n,i,l)=>(await s(`${a(n)}/rows/${encodeURIComponent(i)}`,{method:"PATCH",body:l})).updated,deleteRow:async(n,i)=>(await s(`/${encodeURIComponent(n)}/${encodeURIComponent(i)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await v(`${t}${I}/tables/files/rows?limit=200`,await r())).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 s("/files",{method:"POST",body:{filename:n.name,mime:n.type||"application/octet-stream",data:dt(l),...i===void 0?{}:{message:i}}})},fileLink:async n=>await v(`${t}${I}/files/${encodeURIComponent(n)}/url`,await r()),deleteFile:async n=>(await s(`/files/${encodeURIComponent(n)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await v(`${t}${I}/documents`,await r())).documents,readDocument:async n=>(await v(`${t}${I}/documents/${encodeURIComponent(n)}`,await r())).document,saveDocument:async(n,i)=>await s(`/documents/${encodeURIComponent(n)}`,{method:"PATCH",body:i})}};var T=require("react"),$e="greeting";function be(e,t){if(e.some(a=>a.id===t.id))return e;let o=e.filter(a=>a.id!==$e),r=a=>a.author==="client"==(t.author==="client");return[...o.filter(a=>!(a.pending&&r(a)&&a.text===t.text)),t]}var Oe=(e,t)=>{let[o,r]=(0,T.useState)([]),[s,a]=(0,T.useState)(""),[n,i]=(0,T.useState)(!1),[l,u]=(0,T.useState)(null),d=(0,T.useRef)(0),f=t?.pollMs??2e3;(0,T.useEffect)(()=>{let p=!0;return e.getInfo().then(y=>{p&&y.greeting&&r(h=>h.length===0?[{id:$e,cursor:"",author:"agent",text:y.greeting}]:h)}).catch(()=>{}),()=>{p=!1}},[e]),(0,T.useEffect)(()=>e.subscribe?.({onMessage:p=>r(y=>be(y,p)),onError:p=>u(p.error),onHealthy:()=>u(null)},{intervalMs:f}),[e,f]);let g=(0,T.useCallback)(()=>{let p=s.trim();if(!p||n)return;a(""),u(null),i(!0),d.current+=1;let y=`pending-${d.current}`,h={id:y,cursor:"",author:"client",text:p,pending:!0};r(m=>[...m,h]),e.sendMessage(p).then(m=>{i(!1),m.reply.trim()&&r(c=>c.some(P=>!P.pending&&P.author!=="client"&&P.text===m.reply)?c:(d.current+=1,[...c,{id:`pending-agent-${d.current}`,cursor:"",author:"agent",text:m.reply,pending:!0}]))}).catch(m=>{u(m instanceof Error?m.message:"send_failed"),i(!1),r(D=>D.filter(c=>c.id!==y)),a(D=>D||p)})},[s,n,e]);return{messages:o,input:s,setInput:a,send:g,sending:n,error:l}};0&&(module.exports={Chat,GRID_COLS,GRID_MAX_COLS,GRID_MAX_ROWS,HolaProvider,PortalConflict,bandOfKind,bandOfType,cellValue,createApiTransport,createHolaClient,createPortalData,createWidgetTransport,deliverableCellText,deliverableStatus,deriveFields,footprintOf,footprintWith,formatDeliverableDate,groupDeliverableVersions,inferSpec,isDeliverableChecked,mergeMessage,normalizeDeliverableColType,normalizeDeliverableItem,parseDashboardSpec,parseDeliverableItems,parseDeliverableTable,parseTableResponses,placeWidgets,publishedVersionOf,renderModel,setResponse,splitLayout,textDeltaOf,thinkingDeltaOf,toolEventOf,useArtifactUrl,useChat,useHolaClient,useThread});
8
+ `)}},u=async()=>{let d=await a.read();if(!d.done)return s+=n.decode(d.value,{stream:!0}),l(),u()};await u()};var Xe=/\/+$/,Y="/api/v1/end-user",Re=e=>{let t=e.baseUrl.replace(Xe,""),r=()=>typeof e.token=="function"?e.token():e.token,o=n=>e.project?`${n}project=${encodeURIComponent(e.project)}`:"",i=async()=>({"content-type":"application/json",authorization:`Bearer ${await r()}`}),a=async n=>{let s=await fetch(`${t}${Y}/chat${o("?")}`,{method:"POST",headers:await i(),body:JSON.stringify({message:n})});if(!s.ok)throw new Error(`hola: message failed (${s.status})`);return{reply:(await s.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>v(`${t}${Y}/chat/info${o("?")}`,await i()),sendMessage:a,streamMessage:async(n,s)=>{try{let l=await a(n);s.onText?.(l.reply),s.onComplete?.(l)}catch(l){s.onError?.(C(l))}},subscribe:(n,s)=>{let l=s?.since??"0",u=!1,d,m=s?.intervalMs??3e3,g=typeof document<"u",p=()=>g&&document.visibilityState==="hidden",b=!1,h=()=>{if(!u){if(p()){b=!0;return}d=setTimeout(f,m)}},f=async()=>{try{let y=await v(`${t}${Y}/chat/thread?since=${encodeURIComponent(l)}${o("&")}`,await i());for(let P of y.messages)n.onMessage(P);l=y.cursor,n.onHealthy?.()}catch(y){n.onError?.(C(y))}h()},D=()=>{u||!b||p()||(b=!1,d&&clearTimeout(d),d=setTimeout(f,0))};g&&document.addEventListener("visibilitychange",D);let c=()=>{u=!0,d&&clearTimeout(d),g&&document.removeEventListener("visibilitychange",D)};return s?.signal?.addEventListener("abort",c),d=setTimeout(f,0),c}}};var L=require("react"),U=(e,t)=>{let[r,o]=(0,L.useState)("");return(0,L.useEffect)(()=>{if(!e){o("");return}let i=Uint8Array.from(atob(e),n=>n.charCodeAt(0)),a=URL.createObjectURL(new Blob([i],{type:t}));return o(a),()=>URL.revokeObjectURL(a)},[e,t]),r};var j=require("react");var F=require("react"),Ce=require("react/jsx-runtime"),ke=(0,F.createContext)(null),De=({client:e,children:t})=>(0,Ce.jsx)(ke.Provider,{value:e,children:t}),N=()=>{let e=(0,F.useContext)(ke);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};var w=require("react"),V=e=>{let[t,r]=(0,w.useState)([]),[o,i]=(0,w.useState)(""),[a,n]=(0,w.useState)(!1),[s,l]=(0,w.useState)(null),u=(0,w.useRef)(0),d=(0,w.useRef)(null);(0,w.useEffect)(()=>()=>d.current?.abort(),[]);let m=(0,w.useCallback)(()=>{let p=u.current;return u.current+=1,p},[]);(0,w.useEffect)(()=>{let p=!0;return e.getInfo().then(b=>{p&&b.greeting&&r([{id:m(),role:"assistant",text:b.greeting}])}).catch(()=>{}),()=>{p=!1}},[e,m]);let g=(0,w.useCallback)(()=>{let p=o.trim();if(!p||a)return;i(""),l(null),n(!0);let b=m(),h=m();r(c=>[...c,{id:b,role:"user",text:p},{id:h,role:"assistant",text:"",streaming:!0}]);let f=c=>{r(y=>y.map(P=>P.id===h?c(P):P))},D=new AbortController;d.current=D,e.streamMessage(p,{onText:c=>f(y=>({...y,text:y.text+c})),onComplete:c=>{f(y=>({...y,text:c.reply||y.text,artifacts:c.artifacts,streaming:!1})),n(!1)},onError:c=>{f(y=>({...y,streaming:!1})),l(c.error),n(!1)}},D.signal).catch(c=>{f(y=>({...y,streaming:!1})),l(c instanceof Error?c.message:"stream_failed"),n(!1)}).finally(()=>{n(!1),f(c=>c.streaming?{...c,streaming:!1}:c)})},[o,a,e,m]);return{messages:t,input:o,setInput:i,send:g,sending:a,error:s}};var x=require("react/jsx-runtime"),R={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"}},Ke=({artifact:e})=>{let t=U(e.dataBase64??"",e.mimeType),r=e.url??t;return r?e.mimeType.startsWith("image/")?(0,x.jsx)("a",{href:r,rel:"noopener noreferrer",target:"_blank",children:(0,x.jsx)("img",{alt:e.filename,src:r,style:R.image})}):(0,x.jsx)("a",{download:e.filename,href:r,style:R.link,children:e.filename}):null},Se=()=>{let e=N(),{messages:t,input:r,setInput:o,send:i,sending:a,error:n}=V(e),s=(0,j.useRef)(null);(0,j.useEffect)(()=>{let u=s.current;u&&(u.scrollTop=u.scrollHeight)},[t]);let l=u=>{u.preventDefault(),i()};return(0,x.jsxs)("div",{style:R.root,children:[(0,x.jsx)("div",{ref:s,style:R.log,children:t.map(u=>(0,x.jsxs)("div",{style:u.role==="user"?R.user:R.assistant,children:[u.text||(u.streaming?"\u2026":""),u.artifacts&&u.artifacts.length>0?(0,x.jsx)("div",{style:R.artifacts,children:u.artifacts.map(d=>(0,x.jsx)(Ke,{artifact:d},d.filename))}):null]},u.id))}),n?(0,x.jsx)("div",{style:R.error,children:n}):null,(0,x.jsxs)("form",{onSubmit:l,style:R.form,children:[(0,x.jsx)("input",{"aria-label":"Message",onChange:u=>o(u.target.value),placeholder:"Type a message\u2026",style:R.input,value:r}),(0,x.jsx)("button",{disabled:a||r.trim().length===0,style:R.button,type:"submit",children:"Send"})]})]})};var qe=/\/+$/,G=e=>{let t=e.sessionId,r=e.baseUrl.replace(qe,""),o=n=>`${r}/endpoint/${encodeURIComponent(e.token)}${n}`,i={"content-type":"application/json"},a=(n,s)=>({url:o(n),headers:i,body:JSON.stringify({message:s,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>v(o("/config"),{}),sendMessage:async n=>{let s=await ve(a("/message",n));return t=s.sessionId,s},streamMessage:(n,s,l)=>Te(a("/message/stream",n),s,u=>{t=u},l),subscribe:(n,s)=>{let l=s?.since??"0",u=!1,d,m=s?.intervalMs??3e3,g=async()=>{let b=t;if(b)try{let h=await v(o(`/messages?session=${encodeURIComponent(b)}&since=${encodeURIComponent(l)}`),{});for(let f of h.messages)n.onMessage(f);l=h.cursor,n.onHealthy?.()}catch(h){n.onError?.(C(h))}u||(d=setTimeout(g,m))},p=()=>{u=!0,d&&clearTimeout(d)};return s?.signal?.addEventListener("abort",p),d=setTimeout(g,0),p}}};var Pe=e=>"transport"in e?e.transport:G(e);var Ye=/^https?:\/\//i,Qe=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Ze=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function et(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(Ye.test(e))return"url";if(Qe.test(e))return"date"}return"text"}function Q(e){let t=[],r=new Map;for(let o of e)for(let[i,a]of Object.entries(o.data??{})){if(a==null)continue;let n=r.get(i);n||(n=new Map,r.set(i,n),t.push(i));let s=et(a);n.set(s,(n.get(s)??0)+1)}return t.map(o=>{let i=r.get(o)??new Map,a="text",n=-1;for(let[s,l]of i)l>n&&(n=l,a=s);return{key:o,label:Ze(o),type:a}})}var tt=e=>typeof e=="number"?e:Number(e)||0,Ie=e=>/rate|position|rank|score|percent|avg/i.test(e),nt=/posted|published|sent|completed|shipped|launched|_at/i,rt=new Set(["service","order","end_user_id"]);function Z(e,t){let r=e.filter(l=>!rt.has(l.key)),o=r.filter(l=>l.type==="number").slice(0,3),i=r.find(l=>l.key==="status")??r.find(l=>l.type==="select"),a=r.find(l=>l.type==="date"&&nt.test(l.key))??r.find(l=>l.type==="date"),n=r.filter(l=>l.type==="number"&&!Ie(l.key)).map(l=>({field:l,total:t.reduce((u,d)=>u+tt(d.data[l.key]),0)})).sort((l,u)=>u.total-l.total).find(l=>l.total>0)?.field??null,s=[{type:"stat",label:"Items",agg:"count"}];for(let l of o){let u=Ie(l.key);s.push({type:"stat",metric:l.key,agg:u?"avg":"sum",label:u?`Avg ${l.label.toLowerCase()}`:l.label})}return a&&s.push({type:"line",x:a.key,y:n?.key,agg:"sum",title:n?`${n.label} by day`:"Items by day"}),i&&s.push({type:"donut",groupBy:i.key,title:i.label}),s.push({type:"table",columns:r.map(l=>l.key)}),{version:1,widgets:s}}var ee=6,te=6,ne=4,He={stat:{w:1,h:1},chart:{w:2,h:2},block:{w:6,h:2}},ot=e=>Math.max(1,Math.min(6,Math.round(e))),st=e=>Math.max(1,Math.min(4,Math.round(e)));function W(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function re(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function oe(e){return He[e]}function B(e,t,r){let o=He[e];return{w:t===void 0?o.w:ot(t),h:r===void 0?o.h:st(r)}}function z(e){let t=[],r=[],o=(n,s,l,u)=>{if(n<0||n+l>6)return!1;for(let d=0;d<u;d+=1){let m=r[s+d];if(m){for(let g=0;g<l;g+=1)if(m[n+g])return!1}}return!0},i=(n,s,l,u)=>{for(let d=0;d<u;d+=1){let m=r[s+d]??[];for(let g=0;g<l;g+=1)m[n+g]=!0;r[s+d]=m}},a=(n,s)=>{for(let l=0;;l+=1)for(let u=0;u+n<=6;u+=1)if(o(u,l,n,s))return{gx:u,gy:l}};for(let n of e){let s=B(W(n.kind),n.w,n.h),u=n.gx!==void 0&&n.gy!==void 0&&o(n.gx,n.gy,s.w,s.h)&&n.gx!==void 0&&n.gy!==void 0?{gx:n.gx,gy:n.gy}:a(s.w,s.h);i(u.gx,u.gy,s.w,s.h),t.push({widget:n,gx:u.gx,gy:u.gy,w:s.w,h:s.h})}return t}function se(e){let t=[],r=[];for(let o of e)W(o.kind)==="block"?r.push(o):t.push(o);return{tiles:z(t),blocks:r}}var We=new Set(["service","order","end_user_id"]),Me=e=>typeof e=="number"?e:Number(e)||0,Ae=e=>e==null?"":String(e);function Ee(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 r=t.reduce((o,i)=>o+i,0);return e==="avg"?Math.round(r/t.length*100)/100:r}function it(e,t,r,o){let i=new Map;for(let a of e){let n=new Date(Ae(a.data[t]));if(Number.isNaN(n.getTime()))continue;let s=n.toISOString().slice(0,10),l=i.get(s)??[];l.push(r?Me(a.data[r]):1),i.set(s,l)}return[...i.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:r?Ee(o,n):n.length}))}function at(e,t){let r=new Map;for(let o of e){let i=Ae(o.data[t]).trim();i&&r.set(i,(r.get(i)??0)+1)}return[...r.entries()].sort((o,i)=>i[1]-o[1]).map(([o,i])=>({label:o,value:i}))}function lt(e,t,r,o){switch(e.type){case"stat":{let i=e.metric?t.get(e.metric):void 0;if(e.metric&&!i)return null;if(!i)return{kind:"stat",label:e.label??"Items",value:o.length};let a=o.map(n=>Me(n.data[i.key]));return{kind:"stat",label:e.label??i.label,value:Ee(e.agg??"sum",a)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let i=it(o,e.x,e.y,e.agg??"sum");return i.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:i}}case"donut":{if(!t.has(e.groupBy))return null;let i=at(o,e.groupBy);return i.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:i}}case"table":{let i=e.columns?e.columns.map(a=>t.get(a)).filter(a=>a!==void 0&&!We.has(a.key)):r;return i.length===0?null:{kind:"table",title:e.title,columns:i,rows:o}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function ie(e,t,r){let o=t.filter(n=>!We.has(n.key)),i=new Map(t.map(n=>[n.key,n])),a=[];for(let n of e.widgets){let s=lt(n,i,o,r);s&&a.push({...s,w:n.w,h:n.h,gx:n.gx,gy:n.gy})}return a}var ut=new Set(["sum","avg","count","min","max","last"]),$e=e=>typeof e=="string"&&ut.has(e)?e:void 0,k=e=>typeof e=="string"&&e!==""?e:void 0,M=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,A=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0,S=e=>typeof e=="number"&&e>=0?Math.round(e):void 0;function dt(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",label:k(t.label),metric:k(t.metric),agg:$e(t.agg),w:M(t.w),h:A(t.h),gx:S(t.gx),gy:S(t.gy)};case"line":case"bar":{let r=k(t.x);return r?{type:t.type,title:k(t.title),x:r,y:k(t.y),agg:$e(t.agg),w:M(t.w),h:A(t.h),gx:S(t.gx),gy:S(t.gy)}:null}case"donut":{let r=k(t.groupBy);return r?{type:"donut",title:k(t.title),groupBy:r,w:M(t.w),h:A(t.h),gx:S(t.gx),gy:S(t.gy)}:null}case"table":{let r=Array.isArray(t.columns)?t.columns.filter(o=>typeof o=="string"):void 0;return{type:"table",title:k(t.title),columns:r,w:M(t.w),h:A(t.h),gx:S(t.gx),gy:S(t.gy)}}case"text":{let r=k(t.body);return r?{type:"text",title:k(t.title),body:r,w:M(t.w),h:A(t.h),gx:S(t.gx),gy:S(t.gy)}:null}default:return null}}function ae(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 r=t.widgets;if(!Array.isArray(r))return null;let o=r.map(dt).filter(a=>a!==null);if(o.length===0)return null;let i=t.version;return{version:typeof i=="number"?i:1,title:k(t.title),widgets:o}}function J(e){if(typeof e=="string")return e?{kind:"file",value:e}:null;if(e&&typeof e=="object"){let t=e,r=typeof t.value=="string"?t.value:"",o=t.kind==="link"||t.kind==="text"||t.kind==="table"?t.kind:"file",i=typeof t.v=="number"&&t.v>=1?Math.floor(t.v):void 0;return r?{kind:o,value:r,...i?{v:i}:{}}:null}return null}function X(e){let t=new Map;for(let r of e){let o=r.v??1,i=t.get(o)??[];i.push(r),t.set(o,i)}return[...t.entries()].sort(([r],[o])=>r-o).map(([r,o])=>({v:r,items:o}))}function le(e){let t=e.files;if(typeof t=="string"&&t.trim()!=="")try{let o=JSON.parse(t);if(Array.isArray(o))return o.map(J).filter(i=>i!==null)}catch{}let r=String(e.file??"");return r?[{kind:"file",value:r}]:[]}function ue(e,t,r,o=""){let a=X(e).find(s=>s.v===t)?.items??[],n=a.filter(s=>s.kind==="file").map(s=>r.get(s.value)??"");return a.some(s=>s.kind==="table")&&n.push(o),n.length===0||n.some(s=>s==="")?"awaiting":n.some(s=>s==="revise")?"revise":"accepted"}function de(e){return Number(e.published_version)||0}function K(e){return e==="number"||e==="date"||e==="boolean"||e==="select"||e==="url"?e:e==="link"?"url":e==="checkbox"?"boolean":"text"}function pe(e){try{let t=JSON.parse(e);if(Array.isArray(t.columns)&&Array.isArray(t.rows)&&t.columns.length){let r=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:K(a.type),...a.clientEditable===!0?{clientEditable:!0}:{}})),o=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:{}})),i=typeof t.name=="string"?t.name:void 0;return{columns:r,rows:o,...i?{name:i}:{}}}}catch{}return null}function ce(e){return e==null?"":String(e)}function me(e){return e===!0||e==="true"||e==="1"||e==="yes"||e==="\u2713"}function E(){return{cells:{},verdict:"",comment:""}}function ge(e){if(typeof e!="string"||e.trim()==="")return E();try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t)){let r=t;return{cells:r.cells&&typeof r.cells=="object"?r.cells:r,verdict:r.verdict==="accepted"||r.verdict==="revise"?r.verdict:"",comment:typeof r.comment=="string"?r.comment:""}}}catch{}return E()}function fe(e,t,r){if(e.clientEditable){let o=r.cells[t.id];if(o&&e.key in o)return o[e.key]}return t.cells[e.key]}function be(e,t,r,o){return{...e,cells:{...e.cells,[t]:{...e.cells[t]??{},[r]:o}}}}function ye(e,t,r){return{...e,verdict:t,comment:r}}function he(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 pt=/\/+$/,I="/api/v1/end-user",H=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function ct(e){let t="";for(let o=0;o<e.length;o+=32768)t+=String.fromCharCode(...e.subarray(o,o+32768));return btoa(t)}var Oe=e=>{let t=e.baseUrl.replace(pt,""),r=()=>typeof e.token=="function"?e.token():e.token,o=async()=>({"content-type":"application/json",authorization:`Bearer ${await r()}`}),i=async(n,s)=>{try{let l=await fetch(`${t}${I}${n}`,{method:s.method,headers:await o(),...s.body===void 0?{}:{body:JSON.stringify(s.body)}});if(l.status===409){let u=await l.json().catch(()=>({}));throw new H(u.message??"Someone else saved this first.")}if(!l.ok){let u=await l.text().catch(()=>""),d=`${s.method} ${n} \u2192 ${String(l.status)}`;try{let m=JSON.parse(u);m.message&&(d=m.message)}catch{d=u?`${d}: ${u}`:d}throw C({error:d})}return await l.json()}catch(l){throw l instanceof H?l:C(l)}},a=n=>`/tables/${encodeURIComponent(n)}`;return{listTables:async()=>(await v(`${t}${I}/tables`,await o())).tables,listRows:async(n,s)=>await v(`${t}${I}${a(n)}/rows?limit=${String(s??100)}`,await o()),insertRow:async(n,s)=>{let{rowIds:l}=await i(`${a(n)}/rows`,{method:"POST",body:{rows:[s]}}),u=l[0];if(!u)throw C(new Error("The row was not created."));return u},patchRow:async(n,s,l)=>(await i(`${a(n)}/rows/${encodeURIComponent(s)}`,{method:"PATCH",body:l})).updated,deleteRow:async(n,s)=>(await i(`/${encodeURIComponent(n)}/${encodeURIComponent(s)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await v(`${t}${I}/tables/files/rows?limit=200`,await o())).rows.map(s=>({id:s.rowId,filename:String(s.data.filename??""),source:String(s.data.source??"client"),campaign:String(s.data.campaign??""),size:typeof s.data.size=="number"?s.data.size:0,createdAt:s.createdAt})),uploadFile:async(n,s)=>{let l=new Uint8Array(await n.arrayBuffer());return await i("/files",{method:"POST",body:{filename:n.name,mime:n.type||"application/octet-stream",data:ct(l),...s===void 0?{}:{message:s}}})},fileLink:async n=>await v(`${t}${I}/files/${encodeURIComponent(n)}/url`,await o()),deleteFile:async n=>(await i(`/files/${encodeURIComponent(n)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await v(`${t}${I}/documents`,await o())).documents,readDocument:async n=>(await v(`${t}${I}/documents/${encodeURIComponent(n)}`,await o())).document,saveDocument:async(n,s)=>await i(`/documents/${encodeURIComponent(n)}`,{method:"PATCH",body:s})}};var T=require("react"),_e="greeting";function we(e,t){if(e.some(a=>a.id===t.id))return e;let r=e.filter(a=>a.id!==_e),o=a=>a.author==="client"==(t.author==="client");return[...r.filter(a=>!(a.pending&&o(a)&&a.text===t.text)),t]}var Le=(e,t)=>{let[r,o]=(0,T.useState)([]),[i,a]=(0,T.useState)(""),[n,s]=(0,T.useState)(!1),[l,u]=(0,T.useState)(null),d=(0,T.useRef)(0),m=t?.pollMs??2e3;(0,T.useEffect)(()=>{let p=!0;return e.getInfo().then(b=>{p&&b.greeting&&o(h=>h.length===0?[{id:_e,cursor:"",author:"agent",text:b.greeting}]:h)}).catch(()=>{}),()=>{p=!1}},[e]),(0,T.useEffect)(()=>e.subscribe?.({onMessage:p=>o(b=>we(b,p)),onError:p=>u(p.error),onHealthy:()=>u(null)},{intervalMs:m}),[e,m]);let g=(0,T.useCallback)(()=>{let p=i.trim();if(!p||n)return;a(""),u(null),s(!0),d.current+=1;let b=`pending-${d.current}`,h={id:b,cursor:"",author:"client",text:p,pending:!0};o(f=>[...f,h]),e.sendMessage(p).then(f=>{s(!1),f.reply.trim()&&o(c=>c.some(P=>!P.pending&&P.author!=="client"&&P.text===f.reply)?c:(d.current+=1,[...c,{id:`pending-agent-${d.current}`,cursor:"",author:"agent",text:f.reply,pending:!0}]))}).catch(f=>{u(f instanceof Error?f.message:"send_failed"),s(!1),o(D=>D.filter(c=>c.id!==b)),a(D=>D||p)})},[i,n,e]);return{messages:r,input:i,setInput:a,send:g,sending:n,error:l}};0&&(module.exports={Chat,GRID_COLS,GRID_MAX_COLS,GRID_MAX_ROWS,HolaProvider,PortalConflict,bandOfKind,bandOfType,cellValue,createApiTransport,createHolaClient,createPortalData,createWidgetTransport,deliverableCellText,deliverableStatus,deriveFields,emptyTableResponses,footprintOf,footprintWith,formatDeliverableDate,groupDeliverableVersions,inferSpec,isDeliverableChecked,mergeMessage,normalizeDeliverableColType,normalizeDeliverableItem,parseDashboardSpec,parseDeliverableItems,parseDeliverableTable,parseTableResponses,placeWidgets,publishedVersionOf,renderModel,setResponse,setTableReview,splitLayout,textDeltaOf,thinkingDeltaOf,toolEventOf,useArtifactUrl,useChat,useHolaClient,useThread});
package/dist/index.d.cts CHANGED
@@ -100,9 +100,6 @@ type HolaTransport = {
100
100
  * async artifact. Returns an unsubscribe. Optional: a transport with no receive channel omits
101
101
  * it (callers guard on its presence). */
102
102
  subscribe?(handlers: HolaSubscribeHandlers, options?: HolaSubscribeOptions): () => void;
103
- /** "Talk to a person": ask for a human to take over this conversation. The AI pauses until a
104
- * teammate replies or hands back; the person's messages arrive via `subscribe`. Optional. */
105
- requestHuman?(): Promise<void>;
106
103
  };
107
104
 
108
105
  type ApiTransportConfig = {
@@ -492,7 +489,9 @@ declare function groupDeliverableVersions(items: DeliverableItem[]): Deliverable
492
489
  * bare-string refs; returns [] when there is nothing. */
493
490
  declare function parseDeliverableItems(data: Record<string, unknown>): DeliverableItem[];
494
491
  type DeliverableReviewState = "awaiting" | "accepted" | "revise";
495
- declare function deliverableStatus(items: DeliverableItem[], publishedVersion: number, verdictById: Map<string, string>): DeliverableReviewState;
492
+ declare function deliverableStatus(items: DeliverableItem[], publishedVersion: number, verdictById: Map<string, string>,
493
+ /** The client's verdict on the delivered TABLE (from the deliverable's response), if any. */
494
+ tableVerdict?: "" | "accepted" | "revise"): DeliverableReviewState;
496
495
  /** The version the client currently sees — the EXPLICIT `published_version` pointer the operator set
497
496
  * (0 = nothing published). No `done → latest` fallback: that followed the latest version, so a new
498
497
  * version the team delivered would auto-appear to the client before it was published. */
@@ -529,14 +528,26 @@ declare function deliverableCellText(v: unknown): string;
529
528
  /** Whether a `boolean` cell is checked — tolerant of a real boolean or the string forms it was stored
530
529
  * as across versions. */
531
530
  declare function isDeliverableChecked(v: unknown): boolean;
532
- type TableResponses = Record<string, Record<string, unknown>>;
533
- /** Parse a deliverable's `responses` field (client_tasks.responses) into the rowId→colKey→value map. */
531
+ type TableReviewVerdict = "" | "accepted" | "revise";
532
+ type TableResponses = {
533
+ /** The client's edits to client-editable columns: rowId → columnKey → value. */
534
+ cells: Record<string, Record<string, unknown>>;
535
+ /** The client's review of the table — empty until they submit. */
536
+ verdict: TableReviewVerdict;
537
+ /** The client's comment when sending back (or a note on approve). */
538
+ comment: string;
539
+ };
540
+ declare function emptyTableResponses(): TableResponses;
541
+ /** Parse a deliverable's `responses` field (client_tasks.responses). Tolerant of the legacy bare
542
+ * rowId→colKey map (read as edits with no review yet). */
534
543
  declare function parseTableResponses(value: unknown): TableResponses;
535
- /** The value to SHOW for a cell: the customer's response on a client-editable column, else the
536
- * operator's authored value. */
544
+ /** The value to SHOW for a cell: the customer's edit on a client-editable column, else the operator's
545
+ * authored value. */
537
546
  declare function cellValue(col: DeliverableColumn, row: DeliverableRow, responses: TableResponses): unknown;
538
- /** Merge one client cell edit into a responses map (immutably), for writing back to `responses`. */
547
+ /** Merge one client cell edit into a response (immutably) for the client's local draft. */
539
548
  declare function setResponse(responses: TableResponses, rowId: string, colKey: string, value: unknown): TableResponses;
549
+ /** Set the review verdict + comment (immutably) — for the submit (approve / send back) action. */
550
+ declare function setTableReview(responses: TableResponses, verdict: TableReviewVerdict, comment: string): TableResponses;
540
551
  /** A `date` cell stores YYYY-MM-DD; format it as e.g. "Aug 18, 2026" (raw string if unparseable). */
541
552
  declare function formatDeliverableDate(v: string): string;
542
553
 
@@ -596,4 +607,4 @@ declare const useThread: (client: HolaClient, options?: {
596
607
  pollMs?: number;
597
608
  }) => UseThread;
598
609
 
599
- export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type CreateHolaClientOptions, type DashboardLayout, type DashboardSpec, type DeliverableColType, type DeliverableColumn, type DeliverableItem, type DeliverableItemKind, type DeliverableReviewState, type DeliverableRow, type DeliverableTable, type DeliverableVersion, type DonutWidget, GRID_COLS, 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 PlacedWidget, 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 TableResponses, type TableWidget, type TextWidget, type ThreadMessage, type UseChat, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, cellValue, createApiTransport, createHolaClient, createPortalData, createWidgetTransport, deliverableCellText, deliverableStatus, deriveFields, footprintOf, footprintWith, formatDeliverableDate, groupDeliverableVersions, inferSpec, isDeliverableChecked, mergeMessage, normalizeDeliverableColType, normalizeDeliverableItem, parseDashboardSpec, parseDeliverableItems, parseDeliverableTable, parseTableResponses, placeWidgets, publishedVersionOf, renderModel, setResponse, splitLayout, textDeltaOf, thinkingDeltaOf, toolEventOf, useArtifactUrl, useChat, useHolaClient, useThread };
610
+ export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type CreateHolaClientOptions, type DashboardLayout, type DashboardSpec, type DeliverableColType, type DeliverableColumn, type DeliverableItem, type DeliverableItemKind, type DeliverableReviewState, type DeliverableRow, type DeliverableTable, type DeliverableVersion, type DonutWidget, GRID_COLS, 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 PlacedWidget, 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 TableResponses, type TableReviewVerdict, type TableWidget, type TextWidget, type ThreadMessage, type UseChat, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, cellValue, createApiTransport, createHolaClient, createPortalData, createWidgetTransport, deliverableCellText, deliverableStatus, deriveFields, emptyTableResponses, footprintOf, footprintWith, formatDeliverableDate, groupDeliverableVersions, inferSpec, isDeliverableChecked, mergeMessage, normalizeDeliverableColType, normalizeDeliverableItem, parseDashboardSpec, parseDeliverableItems, parseDeliverableTable, parseTableResponses, placeWidgets, publishedVersionOf, renderModel, setResponse, setTableReview, splitLayout, textDeltaOf, thinkingDeltaOf, toolEventOf, useArtifactUrl, useChat, useHolaClient, useThread };
package/dist/index.d.ts CHANGED
@@ -100,9 +100,6 @@ type HolaTransport = {
100
100
  * async artifact. Returns an unsubscribe. Optional: a transport with no receive channel omits
101
101
  * it (callers guard on its presence). */
102
102
  subscribe?(handlers: HolaSubscribeHandlers, options?: HolaSubscribeOptions): () => void;
103
- /** "Talk to a person": ask for a human to take over this conversation. The AI pauses until a
104
- * teammate replies or hands back; the person's messages arrive via `subscribe`. Optional. */
105
- requestHuman?(): Promise<void>;
106
103
  };
107
104
 
108
105
  type ApiTransportConfig = {
@@ -492,7 +489,9 @@ declare function groupDeliverableVersions(items: DeliverableItem[]): Deliverable
492
489
  * bare-string refs; returns [] when there is nothing. */
493
490
  declare function parseDeliverableItems(data: Record<string, unknown>): DeliverableItem[];
494
491
  type DeliverableReviewState = "awaiting" | "accepted" | "revise";
495
- declare function deliverableStatus(items: DeliverableItem[], publishedVersion: number, verdictById: Map<string, string>): DeliverableReviewState;
492
+ declare function deliverableStatus(items: DeliverableItem[], publishedVersion: number, verdictById: Map<string, string>,
493
+ /** The client's verdict on the delivered TABLE (from the deliverable's response), if any. */
494
+ tableVerdict?: "" | "accepted" | "revise"): DeliverableReviewState;
496
495
  /** The version the client currently sees — the EXPLICIT `published_version` pointer the operator set
497
496
  * (0 = nothing published). No `done → latest` fallback: that followed the latest version, so a new
498
497
  * version the team delivered would auto-appear to the client before it was published. */
@@ -529,14 +528,26 @@ declare function deliverableCellText(v: unknown): string;
529
528
  /** Whether a `boolean` cell is checked — tolerant of a real boolean or the string forms it was stored
530
529
  * as across versions. */
531
530
  declare function isDeliverableChecked(v: unknown): boolean;
532
- type TableResponses = Record<string, Record<string, unknown>>;
533
- /** Parse a deliverable's `responses` field (client_tasks.responses) into the rowId→colKey→value map. */
531
+ type TableReviewVerdict = "" | "accepted" | "revise";
532
+ type TableResponses = {
533
+ /** The client's edits to client-editable columns: rowId → columnKey → value. */
534
+ cells: Record<string, Record<string, unknown>>;
535
+ /** The client's review of the table — empty until they submit. */
536
+ verdict: TableReviewVerdict;
537
+ /** The client's comment when sending back (or a note on approve). */
538
+ comment: string;
539
+ };
540
+ declare function emptyTableResponses(): TableResponses;
541
+ /** Parse a deliverable's `responses` field (client_tasks.responses). Tolerant of the legacy bare
542
+ * rowId→colKey map (read as edits with no review yet). */
534
543
  declare function parseTableResponses(value: unknown): TableResponses;
535
- /** The value to SHOW for a cell: the customer's response on a client-editable column, else the
536
- * operator's authored value. */
544
+ /** The value to SHOW for a cell: the customer's edit on a client-editable column, else the operator's
545
+ * authored value. */
537
546
  declare function cellValue(col: DeliverableColumn, row: DeliverableRow, responses: TableResponses): unknown;
538
- /** Merge one client cell edit into a responses map (immutably), for writing back to `responses`. */
547
+ /** Merge one client cell edit into a response (immutably) for the client's local draft. */
539
548
  declare function setResponse(responses: TableResponses, rowId: string, colKey: string, value: unknown): TableResponses;
549
+ /** Set the review verdict + comment (immutably) — for the submit (approve / send back) action. */
550
+ declare function setTableReview(responses: TableResponses, verdict: TableReviewVerdict, comment: string): TableResponses;
540
551
  /** A `date` cell stores YYYY-MM-DD; format it as e.g. "Aug 18, 2026" (raw string if unparseable). */
541
552
  declare function formatDeliverableDate(v: string): string;
542
553
 
@@ -596,4 +607,4 @@ declare const useThread: (client: HolaClient, options?: {
596
607
  pollMs?: number;
597
608
  }) => UseThread;
598
609
 
599
- export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type CreateHolaClientOptions, type DashboardLayout, type DashboardSpec, type DeliverableColType, type DeliverableColumn, type DeliverableItem, type DeliverableItemKind, type DeliverableReviewState, type DeliverableRow, type DeliverableTable, type DeliverableVersion, type DonutWidget, GRID_COLS, 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 PlacedWidget, 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 TableResponses, type TableWidget, type TextWidget, type ThreadMessage, type UseChat, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, cellValue, createApiTransport, createHolaClient, createPortalData, createWidgetTransport, deliverableCellText, deliverableStatus, deriveFields, footprintOf, footprintWith, formatDeliverableDate, groupDeliverableVersions, inferSpec, isDeliverableChecked, mergeMessage, normalizeDeliverableColType, normalizeDeliverableItem, parseDashboardSpec, parseDeliverableItems, parseDeliverableTable, parseTableResponses, placeWidgets, publishedVersionOf, renderModel, setResponse, splitLayout, textDeltaOf, thinkingDeltaOf, toolEventOf, useArtifactUrl, useChat, useHolaClient, useThread };
610
+ export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type CreateHolaClientOptions, type DashboardLayout, type DashboardSpec, type DeliverableColType, type DeliverableColumn, type DeliverableItem, type DeliverableItemKind, type DeliverableReviewState, type DeliverableRow, type DeliverableTable, type DeliverableVersion, type DonutWidget, GRID_COLS, 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 PlacedWidget, 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 TableResponses, type TableReviewVerdict, type TableWidget, type TextWidget, type ThreadMessage, type UseChat, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, cellValue, createApiTransport, createHolaClient, createPortalData, createWidgetTransport, deliverableCellText, deliverableStatus, deriveFields, emptyTableResponses, footprintOf, footprintWith, formatDeliverableDate, groupDeliverableVersions, inferSpec, isDeliverableChecked, mergeMessage, normalizeDeliverableColType, normalizeDeliverableItem, parseDashboardSpec, parseDeliverableItems, parseDeliverableTable, parseTableResponses, placeWidgets, publishedVersionOf, renderModel, setResponse, setTableReview, splitLayout, textDeltaOf, thinkingDeltaOf, toolEventOf, useArtifactUrl, useChat, useHolaClient, useThread };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  'use client'
2
- var q=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="message_update"?t.assistantMessageEvent??null:null},$=e=>{let t=q(e);return t?.type==="text_delta"&&typeof t.delta=="string"?t.delta:null},O=e=>{let t=q(e);return t?.type==="thinking_delta"&&typeof t.delta=="string"?t.delta:null},_=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 We=/^ /,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"}},Me=e=>{let t="message",o=[];for(let r of e.split(`
3
- `))r.startsWith(":")||(r.startsWith("event:")?t=r.slice(6).trim():r.startsWith("data:")&&o.push(r.slice(5).replace(We,"")));return o.length>0?{event:t,data:o.join(`
4
- `)}:null},Ae=(e,t,o)=>{let r;try{r=JSON.parse(e.data)}catch{return}if(e.event==="session"){let s=r.sessionId;s&&(o(s),t.onSession?.(s));return}if(e.event==="turn_event"){t.onEvent?.(r);let s=$(r);s&&t.onText?.(s);let a=O(r);a&&t.onThinking?.(a);let n=_(r);n&&t.onTool?.(n);return}if(e.event==="chat_completed"){let s=r;o(s.sessionId),t.onComplete?.(s);return}e.event==="chat_error"&&t.onError?.(k(r))},w=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()},X=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()},K=async(e,t,o,r)=>{let s=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body,signal:r});if(!(s.ok&&s.body)){t.onError?.({error:`stream_failed_${s.status}`});return}let a=s.body.getReader(),n=new TextDecoder,i="",l=()=>{let d=i.indexOf(`
2
+ var K=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="message_update"?t.assistantMessageEvent??null:null},$=e=>{let t=K(e);return t?.type==="text_delta"&&typeof t.delta=="string"?t.delta:null},O=e=>{let t=K(e);return t?.type==="thinking_delta"&&typeof t.delta=="string"?t.delta:null},_=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 Ae=/^ /,R=e=>{if(e&&typeof e=="object"){let t=e,r=typeof t.error=="string"?t.error:"request_failed";return typeof t.retryable=="boolean"?{error:r,retryable:t.retryable}:{error:r}}return{error:"request_failed"}},Ee=e=>{let t="message",r=[];for(let o of e.split(`
3
+ `))o.startsWith(":")||(o.startsWith("event:")?t=o.slice(6).trim():o.startsWith("data:")&&r.push(o.slice(5).replace(Ae,"")));return r.length>0?{event:t,data:r.join(`
4
+ `)}:null},$e=(e,t,r)=>{let o;try{o=JSON.parse(e.data)}catch{return}if(e.event==="session"){let i=o.sessionId;i&&(r(i),t.onSession?.(i));return}if(e.event==="turn_event"){t.onEvent?.(o);let i=$(o);i&&t.onText?.(i);let a=O(o);a&&t.onThinking?.(a);let n=_(o);n&&t.onTool?.(n);return}if(e.event==="chat_completed"){let i=o;r(i.sessionId),t.onComplete?.(i);return}e.event==="chat_error"&&t.onError?.(R(o))},w=async(e,t)=>{let r=await fetch(e,{headers:t});if(!r.ok)throw new Error(`hola: request failed (${r.status})`);return await r.json()},q=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()},Y=async(e,t,r,o)=>{let i=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body,signal:o});if(!(i.ok&&i.body)){t.onError?.({error:`stream_failed_${i.status}`});return}let a=i.body.getReader(),n=new TextDecoder,s="",l=()=>{let d=s.indexOf(`
5
5
 
6
- `);for(;d!==-1;){let f=i.slice(0,d);i=i.slice(d+2);let g=Me(f);g&&Ae(g,t,o),d=i.indexOf(`
6
+ `);for(;d!==-1;){let m=s.slice(0,d);s=s.slice(d+2);let g=Ee(m);g&&$e(g,t,r),d=s.indexOf(`
7
7
 
8
- `)}},u=async()=>{let d=await a.read();if(!d.done)return i+=n.decode(d.value,{stream:!0}),l(),u()};await u()};var Ee=/\/+$/,W="/api/v1/end-user",$e=e=>{let t=e.baseUrl.replace(Ee,""),o=()=>typeof e.token=="function"?e.token():e.token,r=n=>e.project?`${n}project=${encodeURIComponent(e.project)}`:"",s=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),a=async n=>{let i=await fetch(`${t}${W}/chat${r("?")}`,{method:"POST",headers:await s(),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()=>w(`${t}${W}/chat/info${r("?")}`,await s()),sendMessage:a,streamMessage:async(n,i)=>{try{let l=await a(n);i.onText?.(l.reply),i.onComplete?.(l)}catch(l){i.onError?.(k(l))}},subscribe:(n,i)=>{let l=i?.since??"0",u=!1,d,f=i?.intervalMs??3e3,g=typeof document<"u",p=()=>g&&document.visibilityState==="hidden",y=!1,h=()=>{if(!u){if(p()){y=!0;return}d=setTimeout(m,f)}},m=async()=>{try{let b=await w(`${t}${W}/chat/thread?since=${encodeURIComponent(l)}${r("&")}`,await s());for(let D of b.messages)n.onMessage(D);l=b.cursor,n.onHealthy?.()}catch(b){n.onError?.(k(b))}h()},T=()=>{u||!y||p()||(y=!1,d&&clearTimeout(d),d=setTimeout(m,0))};g&&document.addEventListener("visibilitychange",T);let c=()=>{u=!0,d&&clearTimeout(d),g&&document.removeEventListener("visibilitychange",T)};return i?.signal?.addEventListener("abort",c),d=setTimeout(m,0),c},requestHuman:async()=>{await fetch(`${t}${W}/chat/request-human${r("?")}`,{method:"POST",headers:await s(),body:"{}"})}}};import{useEffect as Oe,useState as _e}from"react";var L=(e,t)=>{let[o,r]=_e("");return Oe(()=>{if(!e){r("");return}let s=Uint8Array.from(atob(e),n=>n.charCodeAt(0)),a=URL.createObjectURL(new Blob([s],{type:t}));return r(a),()=>URL.revokeObjectURL(a)},[e,t]),o};import{useEffect as Ve,useRef as Ge}from"react";import{createContext as Le,useContext as Ue}from"react";import{jsx as Ne}from"react/jsx-runtime";var Y=Le(null),Fe=({client:e,children:t})=>Ne(Y.Provider,{value:e,children:t}),U=()=>{let e=Ue(Y);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};import{useCallback as Q,useEffect as Z,useRef as ee,useState as M}from"react";var F=e=>{let[t,o]=M([]),[r,s]=M(""),[a,n]=M(!1),[i,l]=M(null),u=ee(0),d=ee(null);Z(()=>()=>d.current?.abort(),[]);let f=Q(()=>{let p=u.current;return u.current+=1,p},[]);Z(()=>{let p=!0;return e.getInfo().then(y=>{p&&y.greeting&&o([{id:f(),role:"assistant",text:y.greeting}])}).catch(()=>{}),()=>{p=!1}},[e,f]);let g=Q(()=>{let p=r.trim();if(!p||a)return;s(""),l(null),n(!0);let y=f(),h=f();o(c=>[...c,{id:y,role:"user",text:p},{id:h,role:"assistant",text:"",streaming:!0}]);let m=c=>{o(b=>b.map(D=>D.id===h?c(D):D))},T=new AbortController;d.current=T,e.streamMessage(p,{onText:c=>m(b=>({...b,text:b.text+c})),onComplete:c=>{m(b=>({...b,text:c.reply||b.text,artifacts:c.artifacts,streaming:!1})),n(!1)},onError:c=>{m(b=>({...b,streaming:!1})),l(c.error),n(!1)}},T.signal).catch(c=>{m(b=>({...b,streaming:!1})),l(c instanceof Error?c.message:"stream_failed"),n(!1)}).finally(()=>{n(!1),m(c=>c.streaming?{...c,streaming:!1}:c)})},[r,a,e,f]);return{messages:t,input:r,setInput:s,send:g,sending:a,error:i}};import{jsx as C,jsxs as N}from"react/jsx-runtime";var x={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"}},je=({artifact:e})=>{let t=L(e.dataBase64??"",e.mimeType),o=e.url??t;return o?e.mimeType.startsWith("image/")?C("a",{href:o,rel:"noopener noreferrer",target:"_blank",children:C("img",{alt:e.filename,src:o,style:x.image})}):C("a",{download:e.filename,href:o,style:x.link,children:e.filename}):null},Be=()=>{let e=U(),{messages:t,input:o,setInput:r,send:s,sending:a,error:n}=F(e),i=Ge(null);Ve(()=>{let u=i.current;u&&(u.scrollTop=u.scrollHeight)},[t]);let l=u=>{u.preventDefault(),s()};return N("div",{style:x.root,children:[C("div",{ref:i,style:x.log,children:t.map(u=>N("div",{style:u.role==="user"?x.user:x.assistant,children:[u.text||(u.streaming?"\u2026":""),u.artifacts&&u.artifacts.length>0?C("div",{style:x.artifacts,children:u.artifacts.map(d=>C(je,{artifact:d},d.filename))}):null]},u.id))}),n?C("div",{style:x.error,children:n}):null,N("form",{onSubmit:l,style:x.form,children:[C("input",{"aria-label":"Message",onChange:u=>r(u.target.value),placeholder:"Type a message\u2026",style:x.input,value:o}),C("button",{disabled:a||o.trim().length===0,style:x.button,type:"submit",children:"Send"})]})]})};var ze=/\/+$/,V=e=>{let t=e.sessionId,o=e.baseUrl.replace(ze,""),r=n=>`${o}/endpoint/${encodeURIComponent(e.token)}${n}`,s={"content-type":"application/json"},a=(n,i)=>({url:r(n),headers:s,body:JSON.stringify({message:i,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>w(r("/config"),{}),sendMessage:async n=>{let i=await X(a("/message",n));return t=i.sessionId,i},streamMessage:(n,i,l)=>K(a("/message/stream",n),i,u=>{t=u},l),subscribe:(n,i)=>{let l=i?.since??"0",u=!1,d,f=i?.intervalMs??3e3,g=async()=>{let y=t;if(y)try{let h=await w(r(`/messages?session=${encodeURIComponent(y)}&since=${encodeURIComponent(l)}`),{});for(let m of h.messages)n.onMessage(m);l=h.cursor,n.onHealthy?.()}catch(h){n.onError?.(k(h))}u||(d=setTimeout(g,f))},p=()=>{u=!0,d&&clearTimeout(d)};return i?.signal?.addEventListener("abort",p),d=setTimeout(g,0),p},requestHuman:async()=>{t&&await fetch(r("/request-human"),{method:"POST",headers:s,body:JSON.stringify({sessionId:t})})}}};var Je=e=>"transport"in e?e.transport:V(e);var qe=/^https?:\/\//i,Xe=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Ke=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function Ye(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(qe.test(e))return"url";if(Xe.test(e))return"date"}return"text"}function te(e){let t=[],o=new Map;for(let r of e)for(let[s,a]of Object.entries(r.data??{})){if(a==null)continue;let n=o.get(s);n||(n=new Map,o.set(s,n),t.push(s));let i=Ye(a);n.set(i,(n.get(i)??0)+1)}return t.map(r=>{let s=o.get(r)??new Map,a="text",n=-1;for(let[i,l]of s)l>n&&(n=l,a=i);return{key:r,label:Ke(r),type:a}})}var Qe=e=>typeof e=="number"?e:Number(e)||0,ne=e=>/rate|position|rank|score|percent|avg/i.test(e),Ze=/posted|published|sent|completed|shipped|launched|_at/i,et=new Set(["service","order","end_user_id"]);function re(e,t){let o=e.filter(l=>!et.has(l.key)),r=o.filter(l=>l.type==="number").slice(0,3),s=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"&&!ne(l.key)).map(l=>({field:l,total:t.reduce((u,d)=>u+Qe(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 r){let u=ne(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"}),s&&i.push({type:"donut",groupBy:s.key,title:s.label}),i.push({type:"table",columns:o.map(l=>l.key)}),{version:1,widgets:i}}var oe=6,se=6,ie=4,ae={stat:{w:1,h:1},chart:{w:2,h:2},block:{w:6,h:2}},tt=e=>Math.max(1,Math.min(6,Math.round(e))),nt=e=>Math.max(1,Math.min(4,Math.round(e)));function A(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function le(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function ue(e){return ae[e]}function G(e,t,o){let r=ae[e];return{w:t===void 0?r.w:tt(t),h:o===void 0?r.h:nt(o)}}function j(e){let t=[],o=[],r=(n,i,l,u)=>{if(n<0||n+l>6)return!1;for(let d=0;d<u;d+=1){let f=o[i+d];if(f){for(let g=0;g<l;g+=1)if(f[n+g])return!1}}return!0},s=(n,i,l,u)=>{for(let d=0;d<u;d+=1){let f=o[i+d]??[];for(let g=0;g<l;g+=1)f[n+g]=!0;o[i+d]=f}},a=(n,i)=>{for(let l=0;;l+=1)for(let u=0;u+n<=6;u+=1)if(r(u,l,n,i))return{gx:u,gy:l}};for(let n of e){let i=G(A(n.kind),n.w,n.h),u=n.gx!==void 0&&n.gy!==void 0&&r(n.gx,n.gy,i.w,i.h)&&n.gx!==void 0&&n.gy!==void 0?{gx:n.gx,gy:n.gy}:a(i.w,i.h);s(u.gx,u.gy,i.w,i.h),t.push({widget:n,gx:u.gx,gy:u.gy,w:i.w,h:i.h})}return t}function de(e){let t=[],o=[];for(let r of e)A(r.kind)==="block"?o.push(r):t.push(r);return{tiles:j(t),blocks:o}}var pe=new Set(["service","order","end_user_id"]),ce=e=>typeof e=="number"?e:Number(e)||0,fe=e=>e==null?"":String(e);function ge(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((r,s)=>r+s,0);return e==="avg"?Math.round(o/t.length*100)/100:o}function rt(e,t,o,r){let s=new Map;for(let a of e){let n=new Date(fe(a.data[t]));if(Number.isNaN(n.getTime()))continue;let i=n.toISOString().slice(0,10),l=s.get(i)??[];l.push(o?ce(a.data[o]):1),s.set(i,l)}return[...s.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?ge(r,n):n.length}))}function ot(e,t){let o=new Map;for(let r of e){let s=fe(r.data[t]).trim();s&&o.set(s,(o.get(s)??0)+1)}return[...o.entries()].sort((r,s)=>s[1]-r[1]).map(([r,s])=>({label:r,value:s}))}function st(e,t,o,r){switch(e.type){case"stat":{let s=e.metric?t.get(e.metric):void 0;if(e.metric&&!s)return null;if(!s)return{kind:"stat",label:e.label??"Items",value:r.length};let a=r.map(n=>ce(n.data[s.key]));return{kind:"stat",label:e.label??s.label,value:ge(e.agg??"sum",a)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let s=rt(r,e.x,e.y,e.agg??"sum");return s.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:s}}case"donut":{if(!t.has(e.groupBy))return null;let s=ot(r,e.groupBy);return s.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:s}}case"table":{let s=e.columns?e.columns.map(a=>t.get(a)).filter(a=>a!==void 0&&!pe.has(a.key)):o;return s.length===0?null:{kind:"table",title:e.title,columns:s,rows:r}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function me(e,t,o){let r=t.filter(n=>!pe.has(n.key)),s=new Map(t.map(n=>[n.key,n])),a=[];for(let n of e.widgets){let i=st(n,s,r,o);i&&a.push({...i,w:n.w,h:n.h,gx:n.gx,gy:n.gy})}return a}var it=new Set(["sum","avg","count","min","max","last"]),ye=e=>typeof e=="string"&&it.has(e)?e:void 0,v=e=>typeof e=="string"&&e!==""?e:void 0,P=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,I=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0,R=e=>typeof e=="number"&&e>=0?Math.round(e):void 0;function at(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",label:v(t.label),metric:v(t.metric),agg:ye(t.agg),w:P(t.w),h:I(t.h),gx:R(t.gx),gy:R(t.gy)};case"line":case"bar":{let o=v(t.x);return o?{type:t.type,title:v(t.title),x:o,y:v(t.y),agg:ye(t.agg),w:P(t.w),h:I(t.h),gx:R(t.gx),gy:R(t.gy)}:null}case"donut":{let o=v(t.groupBy);return o?{type:"donut",title:v(t.title),groupBy:o,w:P(t.w),h:I(t.h),gx:R(t.gx),gy:R(t.gy)}:null}case"table":{let o=Array.isArray(t.columns)?t.columns.filter(r=>typeof r=="string"):void 0;return{type:"table",title:v(t.title),columns:o,w:P(t.w),h:I(t.h),gx:R(t.gx),gy:R(t.gy)}}case"text":{let o=v(t.body);return o?{type:"text",title:v(t.title),body:o,w:P(t.w),h:I(t.h),gx:R(t.gx),gy:R(t.gy)}:null}default:return null}}function be(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 r=o.map(at).filter(a=>a!==null);if(r.length===0)return null;let s=t.version;return{version:typeof s=="number"?s:1,title:v(t.title),widgets:r}}function B(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:"",r=t.kind==="link"||t.kind==="text"||t.kind==="table"?t.kind:"file",s=typeof t.v=="number"&&t.v>=1?Math.floor(t.v):void 0;return o?{kind:r,value:o,...s?{v:s}:{}}:null}return null}function z(e){let t=new Map;for(let o of e){let r=o.v??1,s=t.get(r)??[];s.push(o),t.set(r,s)}return[...t.entries()].sort(([o],[r])=>o-r).map(([o,r])=>({v:o,items:r}))}function he(e){let t=e.files;if(typeof t=="string"&&t.trim()!=="")try{let r=JSON.parse(t);if(Array.isArray(r))return r.map(B).filter(s=>s!==null)}catch{}let o=String(e.file??"");return o?[{kind:"file",value:o}]:[]}function we(e,t,o){let s=(z(e).find(n=>n.v===t)?.items??[]).filter(n=>n.kind==="file").map(n=>n.value),a=s.map(n=>o.get(n)??"");return s.length===0||a.some(n=>n==="")?"awaiting":a.some(n=>n==="revise")?"revise":"accepted"}function xe(e){return Number(e.published_version)||0}function J(e){return e==="number"||e==="date"||e==="boolean"||e==="select"||e==="url"?e:e==="link"?"url":e==="checkbox"?"boolean":"text"}function ve(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:J(a.type),...a.clientEditable===!0?{clientEditable:!0}:{}})),r=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:{}})),s=typeof t.name=="string"?t.name:void 0;return{columns:o,rows:r,...s?{name:s}:{}}}}catch{}return null}function Te(e){return e==null?"":String(e)}function ke(e){return e===!0||e==="true"||e==="1"||e==="yes"||e==="\u2713"}function Re(e){if(typeof e!="string"||e.trim()==="")return{};try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}return{}}function De(e,t,o){if(e.clientEditable){let r=o[t.id];if(r&&e.key in r)return r[e.key]}return t.cells[e.key]}function Ce(e,t,o,r){return{...e,[t]:{...e[t]??{},[o]:r}}}function Se(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 lt=/\/+$/,S="/api/v1/end-user",H=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function ut(e){let t="";for(let r=0;r<e.length;r+=32768)t+=String.fromCharCode(...e.subarray(r,r+32768));return btoa(t)}var dt=e=>{let t=e.baseUrl.replace(lt,""),o=()=>typeof e.token=="function"?e.token():e.token,r=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),s=async(n,i)=>{try{let l=await fetch(`${t}${S}${n}`,{method:i.method,headers:await r(),...i.body===void 0?{}:{body:JSON.stringify(i.body)}});if(l.status===409){let u=await l.json().catch(()=>({}));throw new H(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 f=JSON.parse(u);f.message&&(d=f.message)}catch{d=u?`${d}: ${u}`:d}throw k({error:d})}return await l.json()}catch(l){throw l instanceof H?l:k(l)}},a=n=>`/tables/${encodeURIComponent(n)}`;return{listTables:async()=>(await w(`${t}${S}/tables`,await r())).tables,listRows:async(n,i)=>await w(`${t}${S}${a(n)}/rows?limit=${String(i??100)}`,await r()),insertRow:async(n,i)=>{let{rowIds:l}=await s(`${a(n)}/rows`,{method:"POST",body:{rows:[i]}}),u=l[0];if(!u)throw k(new Error("The row was not created."));return u},patchRow:async(n,i,l)=>(await s(`${a(n)}/rows/${encodeURIComponent(i)}`,{method:"PATCH",body:l})).updated,deleteRow:async(n,i)=>(await s(`/${encodeURIComponent(n)}/${encodeURIComponent(i)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await w(`${t}${S}/tables/files/rows?limit=200`,await r())).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 s("/files",{method:"POST",body:{filename:n.name,mime:n.type||"application/octet-stream",data:ut(l),...i===void 0?{}:{message:i}}})},fileLink:async n=>await w(`${t}${S}/files/${encodeURIComponent(n)}/url`,await r()),deleteFile:async n=>(await s(`/files/${encodeURIComponent(n)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await w(`${t}${S}/documents`,await r())).documents,readDocument:async n=>(await w(`${t}${S}/documents/${encodeURIComponent(n)}`,await r())).document,saveDocument:async(n,i)=>await s(`/documents/${encodeURIComponent(n)}`,{method:"PATCH",body:i})}};import{useCallback as pt,useEffect as Pe,useRef as ct,useState as E}from"react";var Ie="greeting";function He(e,t){if(e.some(a=>a.id===t.id))return e;let o=e.filter(a=>a.id!==Ie),r=a=>a.author==="client"==(t.author==="client");return[...o.filter(a=>!(a.pending&&r(a)&&a.text===t.text)),t]}var ft=(e,t)=>{let[o,r]=E([]),[s,a]=E(""),[n,i]=E(!1),[l,u]=E(null),d=ct(0),f=t?.pollMs??2e3;Pe(()=>{let p=!0;return e.getInfo().then(y=>{p&&y.greeting&&r(h=>h.length===0?[{id:Ie,cursor:"",author:"agent",text:y.greeting}]:h)}).catch(()=>{}),()=>{p=!1}},[e]),Pe(()=>e.subscribe?.({onMessage:p=>r(y=>He(y,p)),onError:p=>u(p.error),onHealthy:()=>u(null)},{intervalMs:f}),[e,f]);let g=pt(()=>{let p=s.trim();if(!p||n)return;a(""),u(null),i(!0),d.current+=1;let y=`pending-${d.current}`,h={id:y,cursor:"",author:"client",text:p,pending:!0};r(m=>[...m,h]),e.sendMessage(p).then(m=>{i(!1),m.reply.trim()&&r(c=>c.some(D=>!D.pending&&D.author!=="client"&&D.text===m.reply)?c:(d.current+=1,[...c,{id:`pending-agent-${d.current}`,cursor:"",author:"agent",text:m.reply,pending:!0}]))}).catch(m=>{u(m instanceof Error?m.message:"send_failed"),i(!1),r(T=>T.filter(c=>c.id!==y)),a(T=>T||p)})},[s,n,e]);return{messages:o,input:s,setInput:a,send:g,sending:n,error:l}};export{Be as Chat,oe as GRID_COLS,se as GRID_MAX_COLS,ie as GRID_MAX_ROWS,Fe as HolaProvider,H as PortalConflict,A as bandOfKind,le as bandOfType,De as cellValue,$e as createApiTransport,Je as createHolaClient,dt as createPortalData,V as createWidgetTransport,Te as deliverableCellText,we as deliverableStatus,te as deriveFields,ue as footprintOf,G as footprintWith,Se as formatDeliverableDate,z as groupDeliverableVersions,re as inferSpec,ke as isDeliverableChecked,He as mergeMessage,J as normalizeDeliverableColType,B as normalizeDeliverableItem,be as parseDashboardSpec,he as parseDeliverableItems,ve as parseDeliverableTable,Re as parseTableResponses,j as placeWidgets,xe as publishedVersionOf,me as renderModel,Ce as setResponse,de as splitLayout,$ as textDeltaOf,O as thinkingDeltaOf,_ as toolEventOf,L as useArtifactUrl,F as useChat,U as useHolaClient,ft as useThread};
8
+ `)}},u=async()=>{let d=await a.read();if(!d.done)return s+=n.decode(d.value,{stream:!0}),l(),u()};await u()};var Oe=/\/+$/,L="/api/v1/end-user",_e=e=>{let t=e.baseUrl.replace(Oe,""),r=()=>typeof e.token=="function"?e.token():e.token,o=n=>e.project?`${n}project=${encodeURIComponent(e.project)}`:"",i=async()=>({"content-type":"application/json",authorization:`Bearer ${await r()}`}),a=async n=>{let s=await fetch(`${t}${L}/chat${o("?")}`,{method:"POST",headers:await i(),body:JSON.stringify({message:n})});if(!s.ok)throw new Error(`hola: message failed (${s.status})`);return{reply:(await s.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>w(`${t}${L}/chat/info${o("?")}`,await i()),sendMessage:a,streamMessage:async(n,s)=>{try{let l=await a(n);s.onText?.(l.reply),s.onComplete?.(l)}catch(l){s.onError?.(R(l))}},subscribe:(n,s)=>{let l=s?.since??"0",u=!1,d,m=s?.intervalMs??3e3,g=typeof document<"u",p=()=>g&&document.visibilityState==="hidden",b=!1,h=()=>{if(!u){if(p()){b=!0;return}d=setTimeout(f,m)}},f=async()=>{try{let y=await w(`${t}${L}/chat/thread?since=${encodeURIComponent(l)}${o("&")}`,await i());for(let D of y.messages)n.onMessage(D);l=y.cursor,n.onHealthy?.()}catch(y){n.onError?.(R(y))}h()},T=()=>{u||!b||p()||(b=!1,d&&clearTimeout(d),d=setTimeout(f,0))};g&&document.addEventListener("visibilitychange",T);let c=()=>{u=!0,d&&clearTimeout(d),g&&document.removeEventListener("visibilitychange",T)};return s?.signal?.addEventListener("abort",c),d=setTimeout(f,0),c}}};import{useEffect as Le,useState as Ue}from"react";var U=(e,t)=>{let[r,o]=Ue("");return Le(()=>{if(!e){o("");return}let i=Uint8Array.from(atob(e),n=>n.charCodeAt(0)),a=URL.createObjectURL(new Blob([i],{type:t}));return o(a),()=>URL.revokeObjectURL(a)},[e,t]),r};import{useEffect as Ge,useRef as Be}from"react";import{createContext as Fe,useContext as Ne}from"react";import{jsx as je}from"react/jsx-runtime";var Q=Fe(null),Ve=({client:e,children:t})=>je(Q.Provider,{value:e,children:t}),F=()=>{let e=Ne(Q);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};import{useCallback as Z,useEffect as ee,useRef as te,useState as W}from"react";var N=e=>{let[t,r]=W([]),[o,i]=W(""),[a,n]=W(!1),[s,l]=W(null),u=te(0),d=te(null);ee(()=>()=>d.current?.abort(),[]);let m=Z(()=>{let p=u.current;return u.current+=1,p},[]);ee(()=>{let p=!0;return e.getInfo().then(b=>{p&&b.greeting&&r([{id:m(),role:"assistant",text:b.greeting}])}).catch(()=>{}),()=>{p=!1}},[e,m]);let g=Z(()=>{let p=o.trim();if(!p||a)return;i(""),l(null),n(!0);let b=m(),h=m();r(c=>[...c,{id:b,role:"user",text:p},{id:h,role:"assistant",text:"",streaming:!0}]);let f=c=>{r(y=>y.map(D=>D.id===h?c(D):D))},T=new AbortController;d.current=T,e.streamMessage(p,{onText:c=>f(y=>({...y,text:y.text+c})),onComplete:c=>{f(y=>({...y,text:c.reply||y.text,artifacts:c.artifacts,streaming:!1})),n(!1)},onError:c=>{f(y=>({...y,streaming:!1})),l(c.error),n(!1)}},T.signal).catch(c=>{f(y=>({...y,streaming:!1})),l(c instanceof Error?c.message:"stream_failed"),n(!1)}).finally(()=>{n(!1),f(c=>c.streaming?{...c,streaming:!1}:c)})},[o,a,e,m]);return{messages:t,input:o,setInput:i,send:g,sending:a,error:s}};import{jsx as C,jsxs as V}from"react/jsx-runtime";var x={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"}},ze=({artifact:e})=>{let t=U(e.dataBase64??"",e.mimeType),r=e.url??t;return r?e.mimeType.startsWith("image/")?C("a",{href:r,rel:"noopener noreferrer",target:"_blank",children:C("img",{alt:e.filename,src:r,style:x.image})}):C("a",{download:e.filename,href:r,style:x.link,children:e.filename}):null},Je=()=>{let e=F(),{messages:t,input:r,setInput:o,send:i,sending:a,error:n}=N(e),s=Be(null);Ge(()=>{let u=s.current;u&&(u.scrollTop=u.scrollHeight)},[t]);let l=u=>{u.preventDefault(),i()};return V("div",{style:x.root,children:[C("div",{ref:s,style:x.log,children:t.map(u=>V("div",{style:u.role==="user"?x.user:x.assistant,children:[u.text||(u.streaming?"\u2026":""),u.artifacts&&u.artifacts.length>0?C("div",{style:x.artifacts,children:u.artifacts.map(d=>C(ze,{artifact:d},d.filename))}):null]},u.id))}),n?C("div",{style:x.error,children:n}):null,V("form",{onSubmit:l,style:x.form,children:[C("input",{"aria-label":"Message",onChange:u=>o(u.target.value),placeholder:"Type a message\u2026",style:x.input,value:r}),C("button",{disabled:a||r.trim().length===0,style:x.button,type:"submit",children:"Send"})]})]})};var Xe=/\/+$/,j=e=>{let t=e.sessionId,r=e.baseUrl.replace(Xe,""),o=n=>`${r}/endpoint/${encodeURIComponent(e.token)}${n}`,i={"content-type":"application/json"},a=(n,s)=>({url:o(n),headers:i,body:JSON.stringify({message:s,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>w(o("/config"),{}),sendMessage:async n=>{let s=await q(a("/message",n));return t=s.sessionId,s},streamMessage:(n,s,l)=>Y(a("/message/stream",n),s,u=>{t=u},l),subscribe:(n,s)=>{let l=s?.since??"0",u=!1,d,m=s?.intervalMs??3e3,g=async()=>{let b=t;if(b)try{let h=await w(o(`/messages?session=${encodeURIComponent(b)}&since=${encodeURIComponent(l)}`),{});for(let f of h.messages)n.onMessage(f);l=h.cursor,n.onHealthy?.()}catch(h){n.onError?.(R(h))}u||(d=setTimeout(g,m))},p=()=>{u=!0,d&&clearTimeout(d)};return s?.signal?.addEventListener("abort",p),d=setTimeout(g,0),p}}};var Ke=e=>"transport"in e?e.transport:j(e);var qe=/^https?:\/\//i,Ye=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Qe=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function Ze(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(qe.test(e))return"url";if(Ye.test(e))return"date"}return"text"}function ne(e){let t=[],r=new Map;for(let o of e)for(let[i,a]of Object.entries(o.data??{})){if(a==null)continue;let n=r.get(i);n||(n=new Map,r.set(i,n),t.push(i));let s=Ze(a);n.set(s,(n.get(s)??0)+1)}return t.map(o=>{let i=r.get(o)??new Map,a="text",n=-1;for(let[s,l]of i)l>n&&(n=l,a=s);return{key:o,label:Qe(o),type:a}})}var et=e=>typeof e=="number"?e:Number(e)||0,re=e=>/rate|position|rank|score|percent|avg/i.test(e),tt=/posted|published|sent|completed|shipped|launched|_at/i,nt=new Set(["service","order","end_user_id"]);function oe(e,t){let r=e.filter(l=>!nt.has(l.key)),o=r.filter(l=>l.type==="number").slice(0,3),i=r.find(l=>l.key==="status")??r.find(l=>l.type==="select"),a=r.find(l=>l.type==="date"&&tt.test(l.key))??r.find(l=>l.type==="date"),n=r.filter(l=>l.type==="number"&&!re(l.key)).map(l=>({field:l,total:t.reduce((u,d)=>u+et(d.data[l.key]),0)})).sort((l,u)=>u.total-l.total).find(l=>l.total>0)?.field??null,s=[{type:"stat",label:"Items",agg:"count"}];for(let l of o){let u=re(l.key);s.push({type:"stat",metric:l.key,agg:u?"avg":"sum",label:u?`Avg ${l.label.toLowerCase()}`:l.label})}return a&&s.push({type:"line",x:a.key,y:n?.key,agg:"sum",title:n?`${n.label} by day`:"Items by day"}),i&&s.push({type:"donut",groupBy:i.key,title:i.label}),s.push({type:"table",columns:r.map(l=>l.key)}),{version:1,widgets:s}}var se=6,ie=6,ae=4,le={stat:{w:1,h:1},chart:{w:2,h:2},block:{w:6,h:2}},rt=e=>Math.max(1,Math.min(6,Math.round(e))),ot=e=>Math.max(1,Math.min(4,Math.round(e)));function M(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function ue(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function de(e){return le[e]}function G(e,t,r){let o=le[e];return{w:t===void 0?o.w:rt(t),h:r===void 0?o.h:ot(r)}}function B(e){let t=[],r=[],o=(n,s,l,u)=>{if(n<0||n+l>6)return!1;for(let d=0;d<u;d+=1){let m=r[s+d];if(m){for(let g=0;g<l;g+=1)if(m[n+g])return!1}}return!0},i=(n,s,l,u)=>{for(let d=0;d<u;d+=1){let m=r[s+d]??[];for(let g=0;g<l;g+=1)m[n+g]=!0;r[s+d]=m}},a=(n,s)=>{for(let l=0;;l+=1)for(let u=0;u+n<=6;u+=1)if(o(u,l,n,s))return{gx:u,gy:l}};for(let n of e){let s=G(M(n.kind),n.w,n.h),u=n.gx!==void 0&&n.gy!==void 0&&o(n.gx,n.gy,s.w,s.h)&&n.gx!==void 0&&n.gy!==void 0?{gx:n.gx,gy:n.gy}:a(s.w,s.h);i(u.gx,u.gy,s.w,s.h),t.push({widget:n,gx:u.gx,gy:u.gy,w:s.w,h:s.h})}return t}function pe(e){let t=[],r=[];for(let o of e)M(o.kind)==="block"?r.push(o):t.push(o);return{tiles:B(t),blocks:r}}var ce=new Set(["service","order","end_user_id"]),me=e=>typeof e=="number"?e:Number(e)||0,ge=e=>e==null?"":String(e);function fe(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 r=t.reduce((o,i)=>o+i,0);return e==="avg"?Math.round(r/t.length*100)/100:r}function st(e,t,r,o){let i=new Map;for(let a of e){let n=new Date(ge(a.data[t]));if(Number.isNaN(n.getTime()))continue;let s=n.toISOString().slice(0,10),l=i.get(s)??[];l.push(r?me(a.data[r]):1),i.set(s,l)}return[...i.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:r?fe(o,n):n.length}))}function it(e,t){let r=new Map;for(let o of e){let i=ge(o.data[t]).trim();i&&r.set(i,(r.get(i)??0)+1)}return[...r.entries()].sort((o,i)=>i[1]-o[1]).map(([o,i])=>({label:o,value:i}))}function at(e,t,r,o){switch(e.type){case"stat":{let i=e.metric?t.get(e.metric):void 0;if(e.metric&&!i)return null;if(!i)return{kind:"stat",label:e.label??"Items",value:o.length};let a=o.map(n=>me(n.data[i.key]));return{kind:"stat",label:e.label??i.label,value:fe(e.agg??"sum",a)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let i=st(o,e.x,e.y,e.agg??"sum");return i.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:i}}case"donut":{if(!t.has(e.groupBy))return null;let i=it(o,e.groupBy);return i.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:i}}case"table":{let i=e.columns?e.columns.map(a=>t.get(a)).filter(a=>a!==void 0&&!ce.has(a.key)):r;return i.length===0?null:{kind:"table",title:e.title,columns:i,rows:o}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function be(e,t,r){let o=t.filter(n=>!ce.has(n.key)),i=new Map(t.map(n=>[n.key,n])),a=[];for(let n of e.widgets){let s=at(n,i,o,r);s&&a.push({...s,w:n.w,h:n.h,gx:n.gx,gy:n.gy})}return a}var lt=new Set(["sum","avg","count","min","max","last"]),ye=e=>typeof e=="string"&&lt.has(e)?e:void 0,v=e=>typeof e=="string"&&e!==""?e:void 0,P=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,I=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0,k=e=>typeof e=="number"&&e>=0?Math.round(e):void 0;function ut(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",label:v(t.label),metric:v(t.metric),agg:ye(t.agg),w:P(t.w),h:I(t.h),gx:k(t.gx),gy:k(t.gy)};case"line":case"bar":{let r=v(t.x);return r?{type:t.type,title:v(t.title),x:r,y:v(t.y),agg:ye(t.agg),w:P(t.w),h:I(t.h),gx:k(t.gx),gy:k(t.gy)}:null}case"donut":{let r=v(t.groupBy);return r?{type:"donut",title:v(t.title),groupBy:r,w:P(t.w),h:I(t.h),gx:k(t.gx),gy:k(t.gy)}:null}case"table":{let r=Array.isArray(t.columns)?t.columns.filter(o=>typeof o=="string"):void 0;return{type:"table",title:v(t.title),columns:r,w:P(t.w),h:I(t.h),gx:k(t.gx),gy:k(t.gy)}}case"text":{let r=v(t.body);return r?{type:"text",title:v(t.title),body:r,w:P(t.w),h:I(t.h),gx:k(t.gx),gy:k(t.gy)}:null}default:return null}}function he(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 r=t.widgets;if(!Array.isArray(r))return null;let o=r.map(ut).filter(a=>a!==null);if(o.length===0)return null;let i=t.version;return{version:typeof i=="number"?i:1,title:v(t.title),widgets:o}}function z(e){if(typeof e=="string")return e?{kind:"file",value:e}:null;if(e&&typeof e=="object"){let t=e,r=typeof t.value=="string"?t.value:"",o=t.kind==="link"||t.kind==="text"||t.kind==="table"?t.kind:"file",i=typeof t.v=="number"&&t.v>=1?Math.floor(t.v):void 0;return r?{kind:o,value:r,...i?{v:i}:{}}:null}return null}function J(e){let t=new Map;for(let r of e){let o=r.v??1,i=t.get(o)??[];i.push(r),t.set(o,i)}return[...t.entries()].sort(([r],[o])=>r-o).map(([r,o])=>({v:r,items:o}))}function we(e){let t=e.files;if(typeof t=="string"&&t.trim()!=="")try{let o=JSON.parse(t);if(Array.isArray(o))return o.map(z).filter(i=>i!==null)}catch{}let r=String(e.file??"");return r?[{kind:"file",value:r}]:[]}function xe(e,t,r,o=""){let a=J(e).find(s=>s.v===t)?.items??[],n=a.filter(s=>s.kind==="file").map(s=>r.get(s.value)??"");return a.some(s=>s.kind==="table")&&n.push(o),n.length===0||n.some(s=>s==="")?"awaiting":n.some(s=>s==="revise")?"revise":"accepted"}function ve(e){return Number(e.published_version)||0}function X(e){return e==="number"||e==="date"||e==="boolean"||e==="select"||e==="url"?e:e==="link"?"url":e==="checkbox"?"boolean":"text"}function Te(e){try{let t=JSON.parse(e);if(Array.isArray(t.columns)&&Array.isArray(t.rows)&&t.columns.length){let r=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:X(a.type),...a.clientEditable===!0?{clientEditable:!0}:{}})),o=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:{}})),i=typeof t.name=="string"?t.name:void 0;return{columns:r,rows:o,...i?{name:i}:{}}}}catch{}return null}function Re(e){return e==null?"":String(e)}function ke(e){return e===!0||e==="true"||e==="1"||e==="yes"||e==="\u2713"}function A(){return{cells:{},verdict:"",comment:""}}function De(e){if(typeof e!="string"||e.trim()==="")return A();try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t)){let r=t;return{cells:r.cells&&typeof r.cells=="object"?r.cells:r,verdict:r.verdict==="accepted"||r.verdict==="revise"?r.verdict:"",comment:typeof r.comment=="string"?r.comment:""}}}catch{}return A()}function Ce(e,t,r){if(e.clientEditable){let o=r.cells[t.id];if(o&&e.key in o)return o[e.key]}return t.cells[e.key]}function Se(e,t,r,o){return{...e,cells:{...e.cells,[t]:{...e.cells[t]??{},[r]:o}}}}function Pe(e,t,r){return{...e,verdict:t,comment:r}}function Ie(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 dt=/\/+$/,S="/api/v1/end-user",H=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function pt(e){let t="";for(let o=0;o<e.length;o+=32768)t+=String.fromCharCode(...e.subarray(o,o+32768));return btoa(t)}var ct=e=>{let t=e.baseUrl.replace(dt,""),r=()=>typeof e.token=="function"?e.token():e.token,o=async()=>({"content-type":"application/json",authorization:`Bearer ${await r()}`}),i=async(n,s)=>{try{let l=await fetch(`${t}${S}${n}`,{method:s.method,headers:await o(),...s.body===void 0?{}:{body:JSON.stringify(s.body)}});if(l.status===409){let u=await l.json().catch(()=>({}));throw new H(u.message??"Someone else saved this first.")}if(!l.ok){let u=await l.text().catch(()=>""),d=`${s.method} ${n} \u2192 ${String(l.status)}`;try{let m=JSON.parse(u);m.message&&(d=m.message)}catch{d=u?`${d}: ${u}`:d}throw R({error:d})}return await l.json()}catch(l){throw l instanceof H?l:R(l)}},a=n=>`/tables/${encodeURIComponent(n)}`;return{listTables:async()=>(await w(`${t}${S}/tables`,await o())).tables,listRows:async(n,s)=>await w(`${t}${S}${a(n)}/rows?limit=${String(s??100)}`,await o()),insertRow:async(n,s)=>{let{rowIds:l}=await i(`${a(n)}/rows`,{method:"POST",body:{rows:[s]}}),u=l[0];if(!u)throw R(new Error("The row was not created."));return u},patchRow:async(n,s,l)=>(await i(`${a(n)}/rows/${encodeURIComponent(s)}`,{method:"PATCH",body:l})).updated,deleteRow:async(n,s)=>(await i(`/${encodeURIComponent(n)}/${encodeURIComponent(s)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await w(`${t}${S}/tables/files/rows?limit=200`,await o())).rows.map(s=>({id:s.rowId,filename:String(s.data.filename??""),source:String(s.data.source??"client"),campaign:String(s.data.campaign??""),size:typeof s.data.size=="number"?s.data.size:0,createdAt:s.createdAt})),uploadFile:async(n,s)=>{let l=new Uint8Array(await n.arrayBuffer());return await i("/files",{method:"POST",body:{filename:n.name,mime:n.type||"application/octet-stream",data:pt(l),...s===void 0?{}:{message:s}}})},fileLink:async n=>await w(`${t}${S}/files/${encodeURIComponent(n)}/url`,await o()),deleteFile:async n=>(await i(`/files/${encodeURIComponent(n)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await w(`${t}${S}/documents`,await o())).documents,readDocument:async n=>(await w(`${t}${S}/documents/${encodeURIComponent(n)}`,await o())).document,saveDocument:async(n,s)=>await i(`/documents/${encodeURIComponent(n)}`,{method:"PATCH",body:s})}};import{useCallback as mt,useEffect as He,useRef as gt,useState as E}from"react";var We="greeting";function Me(e,t){if(e.some(a=>a.id===t.id))return e;let r=e.filter(a=>a.id!==We),o=a=>a.author==="client"==(t.author==="client");return[...r.filter(a=>!(a.pending&&o(a)&&a.text===t.text)),t]}var ft=(e,t)=>{let[r,o]=E([]),[i,a]=E(""),[n,s]=E(!1),[l,u]=E(null),d=gt(0),m=t?.pollMs??2e3;He(()=>{let p=!0;return e.getInfo().then(b=>{p&&b.greeting&&o(h=>h.length===0?[{id:We,cursor:"",author:"agent",text:b.greeting}]:h)}).catch(()=>{}),()=>{p=!1}},[e]),He(()=>e.subscribe?.({onMessage:p=>o(b=>Me(b,p)),onError:p=>u(p.error),onHealthy:()=>u(null)},{intervalMs:m}),[e,m]);let g=mt(()=>{let p=i.trim();if(!p||n)return;a(""),u(null),s(!0),d.current+=1;let b=`pending-${d.current}`,h={id:b,cursor:"",author:"client",text:p,pending:!0};o(f=>[...f,h]),e.sendMessage(p).then(f=>{s(!1),f.reply.trim()&&o(c=>c.some(D=>!D.pending&&D.author!=="client"&&D.text===f.reply)?c:(d.current+=1,[...c,{id:`pending-agent-${d.current}`,cursor:"",author:"agent",text:f.reply,pending:!0}]))}).catch(f=>{u(f instanceof Error?f.message:"send_failed"),s(!1),o(T=>T.filter(c=>c.id!==b)),a(T=>T||p)})},[i,n,e]);return{messages:r,input:i,setInput:a,send:g,sending:n,error:l}};export{Je as Chat,se as GRID_COLS,ie as GRID_MAX_COLS,ae as GRID_MAX_ROWS,Ve as HolaProvider,H as PortalConflict,M as bandOfKind,ue as bandOfType,Ce as cellValue,_e as createApiTransport,Ke as createHolaClient,ct as createPortalData,j as createWidgetTransport,Re as deliverableCellText,xe as deliverableStatus,ne as deriveFields,A as emptyTableResponses,de as footprintOf,G as footprintWith,Ie as formatDeliverableDate,J as groupDeliverableVersions,oe as inferSpec,ke as isDeliverableChecked,Me as mergeMessage,X as normalizeDeliverableColType,z as normalizeDeliverableItem,he as parseDashboardSpec,we as parseDeliverableItems,Te as parseDeliverableTable,De as parseTableResponses,B as placeWidgets,ve as publishedVersionOf,be as renderModel,Se as setResponse,Pe as setTableReview,pe as splitLayout,$ as textDeltaOf,O as thinkingDeltaOf,_ as toolEventOf,U as useArtifactUrl,N as useChat,F as useHolaClient,ft as useThread};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holaboss/client",
3
- "version": "0.2.0-beta.14",
3
+ "version": "0.2.0-beta.16",
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",