@marimo-team/frontend 0.19.3-dev41 → 0.19.3-dev45

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.
@@ -1 +1 @@
1
- import{s as oe}from"./chunk-LvLJmgfZ.js";import{d as be,l as ye,n as H,p as ae,u as we}from"./useEvent-DlWF5OMa.js";import{t as Ne}from"./react-BGmjiNul.js";import{N as ke,ni as m,pn as ze,qr as Ce,ti as Se,w as Oe,__tla as Ae}from"./cells-Cv9PtwL9.js";import"./react-dom-C9fstfnp.js";import{t as se}from"./compiler-runtime-DeeZ7FnK.js";import"./tooltip-CrRUCOBw.js";import{f as ie}from"./hotkeys-uKX61F1_.js";import{v as Ie}from"./utils-CJJIceVn.js";import{t as Le}from"./constants-Bkp4R3bQ.js";import"./config-DFDEcYvy.js";import{t as Me}from"./jsx-runtime-DN_bIXfG.js";import{t as z}from"./button-B8cGZzP5.js";import{t as le}from"./cn-C1rgT0yh.js";import"./dist-CAcX026F.js";import{n as Pe,__tla as Ee}from"./JsonOutput-C8Eo1zBR.js";import"./cjs-Bj40p_Np.js";import"./main-CwSdzVhm.js";import"./useNonce-EAuSVK-5.js";import{r as Re}from"./requests-C0HaHO6a.js";import{t as ne}from"./createLucideIcon-CW2xpJ57.js";import{d as qe,__tla as De}from"./layout-9uQoV-6h.js";import{n as He,t as Ve,__tla as Te}from"./LazyAnyLanguageCodeMirror-Cp2punaU.js";import"./download-24bI2vH0.js";import"./markdown-renderer-DlVqlHOL.js";import{u as Ge}from"./toDate-5JckKRQn.js";import{t as Ue,__tla as Be}from"./cell-editor-gOJZyTG_.js";import{t as Fe}from"./play-BJDBXApx.js";import{t as Je}from"./spinner-C1czjtp7.js";import"./dist-HGZzCB0y.js";import"./dist-CVj-_Iiz.js";import"./dist-BVf1IY4_.js";import"./dist-Cq_4nPfh.js";import"./dist-RKnr9SNh.js";import{r as Ke}from"./useTheme-DfP1CWaW.js";import"./Combination-D1TsGrBC.js";import{t as C}from"./tooltip-CvjcEpZC.js";import"./dates-CdsE1R40.js";import"./popover-DtnzNVk-.js";import"./vega-loader.browser-C8wT63Va.js";import"./defaultLocale-BLUna9fQ.js";import"./defaultLocale-DzliDDTm.js";import"./purify.es-N-2faAGj.js";import{__tla as Qe}from"./chunk-OGVTOU66-CjNLT2C3.js";import"./katex-AwOI3EvM.js";import"./marked.esm-CHnOtnr3.js";import"./es-BITbuY9w.js";import{o as We}from"./focus-D1y1tXyC.js";import{a as Xe}from"./renderShortcut-D0Pei-OA.js";import"./esm-B3JckBtM.js";import{n as Ye,r as Ze,t as me}from"./react-resizable-panels.browser.esm-BqxQegSf.js";import"./name-cell-input-YMoA0SQj.js";import"./Inputs-DmoeP8nh.js";import{__tla as $e}from"./loro_wasm_bg-CghhyG7y.js";import"./ws-itdlXHqs.js";import"./dist-BRZzJw_5.js";import"./dist-P7JHert4.js";import"./dist-CoiWxjLF.js";import"./dist-cVYW_wBR.js";import"./dist-BAmo7Mv9.js";import"./dist-3oAtECdQ.js";import"./dist-D6Pwf0VF.js";import"./dist-D9HMoxdZ.js";import"./dist-JtCdI6tY.js";import"./esm-CCqLcax5.js";import{a as et,i as tt,t as rt}from"./kiosk-mode-DfyjlR7p.js";let ce,ot=Promise.all([(()=>{try{return Ae}catch{}})(),(()=>{try{return Ee}catch{}})(),(()=>{try{return De}catch{}})(),(()=>{try{return Te}catch{}})(),(()=>{try{return Be}catch{}})(),(()=>{try{return Qe}catch{}})(),(()=>{try{return $e}catch{}})()]).then(async()=>{var de=ne("eraser",[["path",{d:"M21 21H8a2 2 0 0 1-1.42-.587l-3.994-3.999a2 2 0 0 1 0-2.828l10-10a2 2 0 0 1 2.829 0l5.999 6a2 2 0 0 1 0 2.828L12.834 21",key:"g5wo59"}],["path",{d:"m5.082 11.09 8.828 8.828",key:"1wx5vj"}]]),pe=ne("history",[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M12 7v5l4 2",key:"1fdv2h"}]]),he=se(),V=oe(Ne(),1),ue=15;const T=Ce("marimo:scratchpadHistory:v1",[],ze),fe=ae(!1),xe=ae(null,(e,s,i)=>{if(i=i.trim(),!i)return;let n=e(T);s(T,[i,...n.filter(c=>c!==i)].slice(0,ue))});var t=oe(Me(),1),_e={hide_code:!1,disabled:!1};const ve=()=>{var re;let e=(0,he.c)(60),s=ke(),[i]=Ie(),{theme:n}=Ke(),c=(0,V.useRef)(null),G=We(),{createNewCell:U,updateCellCode:d}=Oe(),{sendRunScratchpad:p}=Re(),S=tt(),B=et(),l=s.cellRuntime[m],F=l==null?void 0:l.output,O=l==null?void 0:l.status,J=l==null?void 0:l.consoleOutputs,r=((re=s.cellData.__scratch__)==null?void 0:re.code)??"",K=be(xe),[a,h]=ye(fe),u=we(T),A;e[0]!==K||e[1]!==r||e[2]!==p?(A=()=>{p({code:r}),K(r)},e[0]=K,e[1]=r,e[2]=p,e[3]=A):A=e[3];let f=H(A),I;e[4]!==r||e[5]!==U||e[6]!==G?(I=()=>{r.trim()&&U({code:r,before:!1,cellId:G??"__end__"})},e[4]=r,e[5]=U,e[6]=G,e[7]=I):I=e[7];let Q=H(I),L;e[8]!==p||e[9]!==d?(L=()=>{d({cellId:m,code:"",formattingChange:!1}),p({code:""});let o=c.current;o&&o.dispatch({changes:{from:0,to:o.state.doc.length,insert:""}})},e[8]=p,e[9]=d,e[10]=L):L=e[10];let W=H(L),M;e[11]!==h||e[12]!==d?(M=o=>{h(!1),d({cellId:m,code:o,formattingChange:!1});let k=c.current;k&&k.dispatch({changes:{from:0,to:k.state.doc.length,insert:o}})},e[11]=h,e[12]=d,e[13]=M):M=e[13];let X=H(M),[Y,ge]=(0,V.useState)(),P;e[14]!==X||e[15]!==u||e[16]!==a||e[17]!==n?(P=()=>a?(0,t.jsx)("div",{className:"absolute inset-0 z-100 bg-background p-3 border-none overflow-auto",children:(0,t.jsx)("div",{className:"overflow-auto flex flex-col gap-3",children:u.map((o,k)=>(0,t.jsx)("div",{className:"border rounded-md hover:shadow-sm cursor-pointer hover:border-input overflow-hidden",onClick:()=>X(o),children:(0,t.jsx)(V.Suspense,{children:(0,t.jsx)(Ve,{language:"python",theme:n,basicSetup:{highlightActiveLine:!1,highlightActiveLineGutter:!1},value:o.trim(),editable:!1,readOnly:!0})})},k))})}):null,e[14]=X,e[15]=u,e[16]=a,e[17]=n,e[18]=P):P=e[18];let Z=P,E;e[19]!==W||e[20]!==Q||e[21]!==f||e[22]!==u.length||e[23]!==a||e[24]!==h||e[25]!==O?(E=()=>(0,t.jsxs)("div",{className:"flex items-center shrink-0 border-b",children:[(0,t.jsx)(C,{content:Xe("cell.run"),children:(0,t.jsx)(z,{"data-testid":"scratchpad-run-button",onClick:f,disabled:a,variant:"text",size:"xs",children:(0,t.jsx)(Fe,{color:"var(--grass-11)",size:16})})}),(0,t.jsx)(C,{content:"Clear code and outputs",children:(0,t.jsx)(z,{disabled:a,size:"xs",variant:"text",onClick:W,children:(0,t.jsx)(de,{size:16})})}),(0,t.jsx)(rt,{children:(0,t.jsx)(C,{content:"Insert code",children:(0,t.jsx)(z,{disabled:a,size:"xs",variant:"text",onClick:Q,children:(0,t.jsx)(He,{size:16})})})}),(O==="running"||O==="queued")&&(0,t.jsx)(Je,{className:"inline",size:"small"}),(0,t.jsx)("div",{className:"flex-1"}),(0,t.jsx)(C,{content:"Toggle history",children:(0,t.jsx)(z,{size:"xs",variant:"text",className:le(a&&"bg-(--sky-3) rounded-none"),onClick:()=>h(!a),disabled:u.length===0,children:(0,t.jsx)(pe,{size:16})})}),(0,t.jsx)(C,{content:(0,t.jsx)("span",{className:"block max-w-prose",children:"Use this scratchpad to experiment with code without restrictions on variable names. Variables defined here aren't saved to notebook memory, and the code is not saved in the notebook file."}),children:(0,t.jsx)(z,{size:"xs",variant:"text",children:(0,t.jsx)(Ge,{size:16})})})]}),e[19]=W,e[20]=Q,e[21]=f,e[22]=u.length,e[23]=a,e[24]=h,e[25]=O,e[26]=E):E=e[26];let $=E,je=S==="vertical",R;e[27]===Symbol.for("react.memo_cache_sentinel")?(R=Se.create(m),e[27]=R):R=e[27];let x;e[28]===$?x=e[29]:(x=$(),e[28]=$,e[29]=x);let q;e[30]===Symbol.for("react.memo_cache_sentinel")?(q=o=>{c.current=o},e[30]=q):q=e[30];let _;e[31]!==r||e[32]!==f||e[33]!==Y||e[34]!==n||e[35]!==i?(_=(0,t.jsx)("div",{className:"flex-1 overflow-auto",children:(0,t.jsx)(Ue,{theme:n,showPlaceholder:!1,id:m,code:r,config:_e,status:"idle",serializedEditorState:null,runCell:f,userConfig:i,editorViewRef:c,setEditorView:q,hidden:!1,showHiddenCode:ie.NOOP,languageAdapter:Y,setLanguageAdapter:ge})}),e[31]=r,e[32]=f,e[33]=Y,e[34]=n,e[35]=i,e[36]=_):_=e[36];let v;e[37]===Z?v=e[38]:(v=Z(),e[37]=Z,e[38]=v);let g;e[39]!==v||e[40]!==x||e[41]!==_?(g=(0,t.jsx)(me,{defaultSize:40,minSize:20,maxSize:70,children:(0,t.jsxs)("div",{className:"h-full flex flex-col overflow-hidden relative",children:[x,_,v]})}),e[39]=v,e[40]=x,e[41]=_,e[42]=g):g=e[42];let ee=je?"h-1":"w-1",j;e[43]===ee?j=e[44]:(j=le("bg-border hover:bg-primary/50 transition-colors",ee),e[43]=ee,e[44]=j);let b;e[45]===j?b=e[46]:(b=(0,t.jsx)(Ze,{className:j}),e[45]=j,e[46]=b);let y;e[47]===F?y=e[48]:(y=(0,t.jsx)("div",{className:"flex-1 overflow-auto",children:(0,t.jsx)(Pe,{allowExpand:!1,output:F,className:Le.outputArea,cellId:m,stale:!1,loading:!1})}),e[47]=F,e[48]=y);let w;e[49]===J?w=e[50]:(w=(0,t.jsx)("div",{className:"overflow-auto shrink-0 max-h-[50%]",children:(0,t.jsx)(qe,{consoleOutputs:J,className:"overflow-auto",stale:!1,cellName:"_",onSubmitDebugger:ie.NOOP,cellId:m,debuggerActive:!1})}),e[49]=J,e[50]=w);let N;e[51]!==y||e[52]!==w?(N=(0,t.jsx)(me,{defaultSize:60,minSize:20,children:(0,t.jsxs)("div",{className:"h-full flex flex-col divide-y overflow-hidden",children:[y,w]})}),e[51]=y,e[52]=w,e[53]=N):N=e[53];let D;return e[54]!==S||e[55]!==B||e[56]!==g||e[57]!==b||e[58]!==N?(D=(0,t.jsx)("div",{className:"flex flex-col h-full overflow-hidden",id:R,children:(0,t.jsxs)(Ye,{direction:S,className:"h-full",children:[g,b,N]},B)}),e[54]=S,e[55]=B,e[56]=g,e[57]=b,e[58]=N,e[59]=D):D=e[59],D};let te;te=se(),ce=()=>{let e=(0,te.c)(1),s;return e[0]===Symbol.for("react.memo_cache_sentinel")?(s=(0,t.jsx)(ve,{}),e[0]=s):s=e[0],s}});export{ot as __tla,ce as default};
1
+ import{s as oe}from"./chunk-LvLJmgfZ.js";import{d as be,l as ye,n as H,p as ae,u as we}from"./useEvent-DlWF5OMa.js";import{t as Ne}from"./react-BGmjiNul.js";import{N as ke,ni as m,pn as ze,qr as Ce,ti as Se,w as Oe,__tla as Ae}from"./cells-Cv9PtwL9.js";import"./react-dom-C9fstfnp.js";import{t as se}from"./compiler-runtime-DeeZ7FnK.js";import"./tooltip-CrRUCOBw.js";import{f as ie}from"./hotkeys-uKX61F1_.js";import{v as Ie}from"./utils-CJJIceVn.js";import{t as Le}from"./constants-Bkp4R3bQ.js";import"./config-DFDEcYvy.js";import{t as Me}from"./jsx-runtime-DN_bIXfG.js";import{t as z}from"./button-B8cGZzP5.js";import{t as le}from"./cn-C1rgT0yh.js";import"./dist-CAcX026F.js";import{n as Pe,__tla as Ee}from"./JsonOutput-C8Eo1zBR.js";import"./cjs-Bj40p_Np.js";import"./main-CwSdzVhm.js";import"./useNonce-EAuSVK-5.js";import{r as Re}from"./requests-C0HaHO6a.js";import{t as ne}from"./createLucideIcon-CW2xpJ57.js";import{d as qe,__tla as De}from"./layout-9uQoV-6h.js";import{n as He,t as Ve,__tla as Te}from"./LazyAnyLanguageCodeMirror-Cp2punaU.js";import"./download-24bI2vH0.js";import"./markdown-renderer-DlVqlHOL.js";import{u as Ge}from"./toDate-5JckKRQn.js";import{t as Ue,__tla as Be}from"./cell-editor-Do6lWWk9.js";import{t as Fe}from"./play-BJDBXApx.js";import{t as Je}from"./spinner-C1czjtp7.js";import"./dist-HGZzCB0y.js";import"./dist-CVj-_Iiz.js";import"./dist-BVf1IY4_.js";import"./dist-Cq_4nPfh.js";import"./dist-RKnr9SNh.js";import{r as Ke}from"./useTheme-DfP1CWaW.js";import"./Combination-D1TsGrBC.js";import{t as C}from"./tooltip-CvjcEpZC.js";import"./dates-CdsE1R40.js";import"./popover-DtnzNVk-.js";import"./vega-loader.browser-C8wT63Va.js";import"./defaultLocale-BLUna9fQ.js";import"./defaultLocale-DzliDDTm.js";import"./purify.es-N-2faAGj.js";import{__tla as Qe}from"./chunk-OGVTOU66-CjNLT2C3.js";import"./katex-AwOI3EvM.js";import"./marked.esm-CHnOtnr3.js";import"./es-BITbuY9w.js";import{o as We}from"./focus-D1y1tXyC.js";import{a as Xe}from"./renderShortcut-D0Pei-OA.js";import"./esm-B3JckBtM.js";import{n as Ye,r as Ze,t as me}from"./react-resizable-panels.browser.esm-BqxQegSf.js";import"./name-cell-input-YMoA0SQj.js";import"./Inputs-DmoeP8nh.js";import{__tla as $e}from"./loro_wasm_bg-CghhyG7y.js";import"./ws-itdlXHqs.js";import"./dist-BRZzJw_5.js";import"./dist-P7JHert4.js";import"./dist-CoiWxjLF.js";import"./dist-cVYW_wBR.js";import"./dist-BAmo7Mv9.js";import"./dist-3oAtECdQ.js";import"./dist-D6Pwf0VF.js";import"./dist-D9HMoxdZ.js";import"./dist-JtCdI6tY.js";import"./esm-CCqLcax5.js";import{a as et,i as tt,t as rt}from"./kiosk-mode-DfyjlR7p.js";let ce,ot=Promise.all([(()=>{try{return Ae}catch{}})(),(()=>{try{return Ee}catch{}})(),(()=>{try{return De}catch{}})(),(()=>{try{return Te}catch{}})(),(()=>{try{return Be}catch{}})(),(()=>{try{return Qe}catch{}})(),(()=>{try{return $e}catch{}})()]).then(async()=>{var de=ne("eraser",[["path",{d:"M21 21H8a2 2 0 0 1-1.42-.587l-3.994-3.999a2 2 0 0 1 0-2.828l10-10a2 2 0 0 1 2.829 0l5.999 6a2 2 0 0 1 0 2.828L12.834 21",key:"g5wo59"}],["path",{d:"m5.082 11.09 8.828 8.828",key:"1wx5vj"}]]),pe=ne("history",[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M12 7v5l4 2",key:"1fdv2h"}]]),he=se(),V=oe(Ne(),1),ue=15;const T=Ce("marimo:scratchpadHistory:v1",[],ze),fe=ae(!1),xe=ae(null,(e,s,i)=>{if(i=i.trim(),!i)return;let n=e(T);s(T,[i,...n.filter(c=>c!==i)].slice(0,ue))});var t=oe(Me(),1),_e={hide_code:!1,disabled:!1};const ve=()=>{var re;let e=(0,he.c)(60),s=ke(),[i]=Ie(),{theme:n}=Ke(),c=(0,V.useRef)(null),G=We(),{createNewCell:U,updateCellCode:d}=Oe(),{sendRunScratchpad:p}=Re(),S=tt(),B=et(),l=s.cellRuntime[m],F=l==null?void 0:l.output,O=l==null?void 0:l.status,J=l==null?void 0:l.consoleOutputs,r=((re=s.cellData.__scratch__)==null?void 0:re.code)??"",K=be(xe),[a,h]=ye(fe),u=we(T),A;e[0]!==K||e[1]!==r||e[2]!==p?(A=()=>{p({code:r}),K(r)},e[0]=K,e[1]=r,e[2]=p,e[3]=A):A=e[3];let f=H(A),I;e[4]!==r||e[5]!==U||e[6]!==G?(I=()=>{r.trim()&&U({code:r,before:!1,cellId:G??"__end__"})},e[4]=r,e[5]=U,e[6]=G,e[7]=I):I=e[7];let Q=H(I),L;e[8]!==p||e[9]!==d?(L=()=>{d({cellId:m,code:"",formattingChange:!1}),p({code:""});let o=c.current;o&&o.dispatch({changes:{from:0,to:o.state.doc.length,insert:""}})},e[8]=p,e[9]=d,e[10]=L):L=e[10];let W=H(L),M;e[11]!==h||e[12]!==d?(M=o=>{h(!1),d({cellId:m,code:o,formattingChange:!1});let k=c.current;k&&k.dispatch({changes:{from:0,to:k.state.doc.length,insert:o}})},e[11]=h,e[12]=d,e[13]=M):M=e[13];let X=H(M),[Y,ge]=(0,V.useState)(),P;e[14]!==X||e[15]!==u||e[16]!==a||e[17]!==n?(P=()=>a?(0,t.jsx)("div",{className:"absolute inset-0 z-100 bg-background p-3 border-none overflow-auto",children:(0,t.jsx)("div",{className:"overflow-auto flex flex-col gap-3",children:u.map((o,k)=>(0,t.jsx)("div",{className:"border rounded-md hover:shadow-sm cursor-pointer hover:border-input overflow-hidden",onClick:()=>X(o),children:(0,t.jsx)(V.Suspense,{children:(0,t.jsx)(Ve,{language:"python",theme:n,basicSetup:{highlightActiveLine:!1,highlightActiveLineGutter:!1},value:o.trim(),editable:!1,readOnly:!0})})},k))})}):null,e[14]=X,e[15]=u,e[16]=a,e[17]=n,e[18]=P):P=e[18];let Z=P,E;e[19]!==W||e[20]!==Q||e[21]!==f||e[22]!==u.length||e[23]!==a||e[24]!==h||e[25]!==O?(E=()=>(0,t.jsxs)("div",{className:"flex items-center shrink-0 border-b",children:[(0,t.jsx)(C,{content:Xe("cell.run"),children:(0,t.jsx)(z,{"data-testid":"scratchpad-run-button",onClick:f,disabled:a,variant:"text",size:"xs",children:(0,t.jsx)(Fe,{color:"var(--grass-11)",size:16})})}),(0,t.jsx)(C,{content:"Clear code and outputs",children:(0,t.jsx)(z,{disabled:a,size:"xs",variant:"text",onClick:W,children:(0,t.jsx)(de,{size:16})})}),(0,t.jsx)(rt,{children:(0,t.jsx)(C,{content:"Insert code",children:(0,t.jsx)(z,{disabled:a,size:"xs",variant:"text",onClick:Q,children:(0,t.jsx)(He,{size:16})})})}),(O==="running"||O==="queued")&&(0,t.jsx)(Je,{className:"inline",size:"small"}),(0,t.jsx)("div",{className:"flex-1"}),(0,t.jsx)(C,{content:"Toggle history",children:(0,t.jsx)(z,{size:"xs",variant:"text",className:le(a&&"bg-(--sky-3) rounded-none"),onClick:()=>h(!a),disabled:u.length===0,children:(0,t.jsx)(pe,{size:16})})}),(0,t.jsx)(C,{content:(0,t.jsx)("span",{className:"block max-w-prose",children:"Use this scratchpad to experiment with code without restrictions on variable names. Variables defined here aren't saved to notebook memory, and the code is not saved in the notebook file."}),children:(0,t.jsx)(z,{size:"xs",variant:"text",children:(0,t.jsx)(Ge,{size:16})})})]}),e[19]=W,e[20]=Q,e[21]=f,e[22]=u.length,e[23]=a,e[24]=h,e[25]=O,e[26]=E):E=e[26];let $=E,je=S==="vertical",R;e[27]===Symbol.for("react.memo_cache_sentinel")?(R=Se.create(m),e[27]=R):R=e[27];let x;e[28]===$?x=e[29]:(x=$(),e[28]=$,e[29]=x);let q;e[30]===Symbol.for("react.memo_cache_sentinel")?(q=o=>{c.current=o},e[30]=q):q=e[30];let _;e[31]!==r||e[32]!==f||e[33]!==Y||e[34]!==n||e[35]!==i?(_=(0,t.jsx)("div",{className:"flex-1 overflow-auto",children:(0,t.jsx)(Ue,{theme:n,showPlaceholder:!1,id:m,code:r,config:_e,status:"idle",serializedEditorState:null,runCell:f,userConfig:i,editorViewRef:c,setEditorView:q,hidden:!1,showHiddenCode:ie.NOOP,languageAdapter:Y,setLanguageAdapter:ge})}),e[31]=r,e[32]=f,e[33]=Y,e[34]=n,e[35]=i,e[36]=_):_=e[36];let v;e[37]===Z?v=e[38]:(v=Z(),e[37]=Z,e[38]=v);let g;e[39]!==v||e[40]!==x||e[41]!==_?(g=(0,t.jsx)(me,{defaultSize:40,minSize:20,maxSize:70,children:(0,t.jsxs)("div",{className:"h-full flex flex-col overflow-hidden relative",children:[x,_,v]})}),e[39]=v,e[40]=x,e[41]=_,e[42]=g):g=e[42];let ee=je?"h-1":"w-1",j;e[43]===ee?j=e[44]:(j=le("bg-border hover:bg-primary/50 transition-colors",ee),e[43]=ee,e[44]=j);let b;e[45]===j?b=e[46]:(b=(0,t.jsx)(Ze,{className:j}),e[45]=j,e[46]=b);let y;e[47]===F?y=e[48]:(y=(0,t.jsx)("div",{className:"flex-1 overflow-auto",children:(0,t.jsx)(Pe,{allowExpand:!1,output:F,className:Le.outputArea,cellId:m,stale:!1,loading:!1})}),e[47]=F,e[48]=y);let w;e[49]===J?w=e[50]:(w=(0,t.jsx)("div",{className:"overflow-auto shrink-0 max-h-[50%]",children:(0,t.jsx)(qe,{consoleOutputs:J,className:"overflow-auto",stale:!1,cellName:"_",onSubmitDebugger:ie.NOOP,cellId:m,debuggerActive:!1})}),e[49]=J,e[50]=w);let N;e[51]!==y||e[52]!==w?(N=(0,t.jsx)(me,{defaultSize:60,minSize:20,children:(0,t.jsxs)("div",{className:"h-full flex flex-col divide-y overflow-hidden",children:[y,w]})}),e[51]=y,e[52]=w,e[53]=N):N=e[53];let D;return e[54]!==S||e[55]!==B||e[56]!==g||e[57]!==b||e[58]!==N?(D=(0,t.jsx)("div",{className:"flex flex-col h-full overflow-hidden",id:R,children:(0,t.jsxs)(Ye,{direction:S,className:"h-full",children:[g,b,N]},B)}),e[54]=S,e[55]=B,e[56]=g,e[57]=b,e[58]=N,e[59]=D):D=e[59],D};let te;te=se(),ce=()=>{let e=(0,te.c)(1),s;return e[0]===Symbol.for("react.memo_cache_sentinel")?(s=(0,t.jsx)(ve,{}),e[0]=s):s=e[0],s}});export{ot as __tla,ce as default};
package/dist/index.html CHANGED
@@ -66,7 +66,7 @@
66
66
  <marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
67
67
  <!-- /TODO -->
68
68
  <title>{{ title }}</title>
69
- <script type="module" crossorigin src="./assets/index-Bq3Xa2YC.js"></script>
69
+ <script type="module" crossorigin src="./assets/index-VUoDw_Qb.js"></script>
70
70
  <link rel="modulepreload" crossorigin href="./assets/preload-helper-BW0IMuFq.js">
71
71
  <link rel="modulepreload" crossorigin href="./assets/hotkeys-uKX61F1_.js">
72
72
  <link rel="modulepreload" crossorigin href="./assets/defaultLocale-BLUna9fQ.js">
@@ -209,7 +209,7 @@
209
209
  <link rel="modulepreload" crossorigin href="./assets/blob-Dg_vNTSs.js">
210
210
  <link rel="modulepreload" crossorigin href="./assets/objectWithoutPropertiesLoose-CboCOq4o.js">
211
211
  <link rel="modulepreload" crossorigin href="./assets/esm-B3JckBtM.js">
212
- <link rel="modulepreload" crossorigin href="./assets/add-cell-with-ai-Csh7GHT3.js">
212
+ <link rel="modulepreload" crossorigin href="./assets/add-cell-with-ai-D2qS3Nos.js">
213
213
  <link rel="modulepreload" crossorigin href="./assets/chart-no-axes-column-D42sFB6d.js">
214
214
  <link rel="modulepreload" crossorigin href="./assets/square-function-DxXFdbn8.js">
215
215
  <link rel="modulepreload" crossorigin href="./assets/spec-qp_XZeSS.js">
@@ -257,7 +257,7 @@
257
257
  <link rel="stylesheet" crossorigin href="./assets/cells-jmgGt1lS.css">
258
258
  <link rel="stylesheet" crossorigin href="./assets/markdown-renderer-DdDKmWlR.css">
259
259
  <link rel="stylesheet" crossorigin href="./assets/JsonOutput-B7vuddcd.css">
260
- <link rel="stylesheet" crossorigin href="./assets/index-__6MNWbe.css">
260
+ <link rel="stylesheet" crossorigin href="./assets/index-C30GhE0W.css">
261
261
  </head>
262
262
  <body>
263
263
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/frontend",
3
- "version": "0.19.3-dev41",
3
+ "version": "0.19.3-dev45",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -8,7 +8,6 @@ import type {
8
8
  InvokeAiToolRequest,
9
9
  InvokeAiToolResponse,
10
10
  } from "@/core/network/types";
11
- import type { ChatMessage } from "@/plugins/impl/chat/types";
12
11
  import { blobToString } from "@/utils/fileToBase64";
13
12
  import { Logger } from "@/utils/Logger";
14
13
  import { getAICompletionBodyWithAttachments } from "../editor/ai/completion-utils";
@@ -68,7 +67,6 @@ function stringifyTextParts(parts: UIMessage["parts"]): string {
68
67
  export async function buildCompletionRequestBody(
69
68
  messages: UIMessage[],
70
69
  ): Promise<{
71
- messages: ChatMessage[]; // Deprecated. TODO: Remove in the future
72
70
  uiMessages: UIMessage[];
73
71
  context?: (null | components["schemas"]["AiCompletionContext"]) | undefined;
74
72
  includeOtherCode: string;
@@ -91,25 +89,8 @@ export async function buildCompletionRequestBody(
91
89
  };
92
90
  }
93
91
 
94
- function toChatMessage(message: UIMessage, isLast: boolean): ChatMessage {
95
- // Clone parts to avoid mutating the original message
96
- const parts = [...message.parts];
97
- if (isLast) {
98
- parts.push(...completionBody.attachments);
99
- }
100
- return {
101
- id: message.id,
102
- role: message.role,
103
- content: stringifyTextParts(message.parts), // This is no longer used in the backend
104
- parts,
105
- };
106
- }
107
-
108
92
  return {
109
93
  ...completionBody.body,
110
- messages: messages.map((m, idx) =>
111
- toChatMessage(m, idx === messages.length - 1),
112
- ),
113
94
  uiMessages: messages.map((m, idx) =>
114
95
  addAttachmentsToMessage(m, idx === messages.length - 1),
115
96
  ),
@@ -124,7 +124,7 @@ export const AcceptCompletionButton: React.FC<{
124
124
  size={size}
125
125
  disabled={isLoading}
126
126
  onClick={handleAcceptAndRun}
127
- className={`${baseClasses} rounded-l-none px-1.5 ${borderless && "border-0 border-l-1"} ${playButtonStyles}`}
127
+ className={`${baseClasses} rounded-l-none px-1.5 ${borderless && "border-0 border-l"} ${playButtonStyles}`}
128
128
  >
129
129
  <PlayIcon className="h-2.5 w-2.5" />
130
130
  </Button>
@@ -15,7 +15,7 @@ export type PluginFunctions = {
15
15
  get_chat_history: (req: {}) => Promise<{ messages: UIMessage[] }>;
16
16
  delete_chat_history: (req: {}) => Promise<null>;
17
17
  delete_chat_message: (req: { index: number }) => Promise<null>;
18
- send_prompt: (req: SendMessageRequest) => Promise<string | null>;
18
+ send_prompt: (req: SendMessageRequest) => Promise<unknown>;
19
19
  };
20
20
 
21
21
  const messageSchema = z.array(
@@ -47,7 +47,6 @@ export const ChatPlugin = createPlugin<{ messages: UIMessage[] }>(
47
47
  maxHeight: z.number().optional(),
48
48
  config: configSchema,
49
49
  allowAttachments: z.union([z.boolean(), z.string().array()]),
50
- frontendManaged: z.boolean(),
51
50
  }),
52
51
  )
53
52
  .withFunctions<PluginFunctions>({
@@ -67,7 +66,7 @@ export const ChatPlugin = createPlugin<{ messages: UIMessage[] }>(
67
66
  config: configSchema,
68
67
  }),
69
68
  )
70
- .output(z.union([z.string(), z.null()])),
69
+ .output(z.unknown()),
71
70
  })
72
71
  .renderer((props) => (
73
72
  <TooltipProvider>
@@ -77,7 +76,6 @@ export const ChatPlugin = createPlugin<{ messages: UIMessage[] }>(
77
76
  showConfigurationControls={props.data.showConfigurationControls}
78
77
  maxHeight={props.data.maxHeight}
79
78
  allowAttachments={props.data.allowAttachments}
80
- frontendManaged={props.data.frontendManaged}
81
79
  config={props.data.config}
82
80
  get_chat_history={props.functions.get_chat_history}
83
81
  delete_chat_history={props.functions.delete_chat_history}
@@ -66,7 +66,6 @@ interface Props extends PluginFunctions {
66
66
  showConfigurationControls: boolean;
67
67
  maxHeight: number | undefined;
68
68
  allowAttachments: boolean | string[];
69
- frontendManaged: boolean;
70
69
  value: UIMessage[];
71
70
  setValue: (messages: UIMessage[]) => void;
72
71
  host: HTMLElement;
@@ -166,113 +165,42 @@ export const Chatbot: React.FC<Props> = (props) => {
166
165
  };
167
166
  });
168
167
 
169
- if (props.frontendManaged) {
170
- const stream = new ReadableStream<UIMessageChunk>({
171
- start(controller) {
172
- frontendStreamControllerRef.current = controller;
168
+ const stream = new ReadableStream<UIMessageChunk>({
169
+ start(controller) {
170
+ frontendStreamControllerRef.current = controller;
173
171
 
174
- const abortHandler = () => {
175
- try {
176
- controller.close();
177
- } catch (error) {
178
- Logger.debug("Controller may already be closed", { error });
179
- }
180
- frontendStreamControllerRef.current = null;
181
- };
182
- signal?.addEventListener("abort", abortHandler);
183
-
184
- return () => {
185
- signal?.removeEventListener("abort", abortHandler);
186
- };
187
- },
188
- cancel() {
189
- frontendStreamControllerRef.current = null;
190
- },
191
- });
192
-
193
- // Start the prompt, chunks will be sent via events
194
- props
195
- .send_prompt({
196
- messages: messages,
197
- config: chatConfig,
198
- })
199
- .catch((error: Error) => {
200
- frontendStreamControllerRef.current?.error(error);
201
- frontendStreamControllerRef.current = null;
202
- });
203
-
204
- return createUIMessageStreamResponse({ stream });
205
- }
206
-
207
- if (signal?.aborted) {
208
- return new Response("Aborted", { status: 499 });
209
- }
210
-
211
- // Create a placeholder message for streaming (backend-managed)
212
- const messageId = Date.now().toString();
213
-
214
- setMessages((prev) => [
215
- ...prev,
216
- {
217
- id: messageId,
218
- role: "assistant",
219
- parts: [{ type: "text", text: "" }],
220
- },
221
- ]);
222
-
223
- // Create an abort-aware promise for the send_prompt call
224
- const sendPromptPromise = props.send_prompt({
225
- messages: messages,
226
- config: chatConfig,
227
- });
228
-
229
- // Race the send_prompt with an abort signal
230
- const response = await new Promise<string | null>(
231
- (resolve, reject) => {
232
- // Listen for abort
233
172
  const abortHandler = () => {
234
- reject(new DOMException("Aborted", "AbortError"));
173
+ try {
174
+ controller.close();
175
+ } catch (error) {
176
+ Logger.debug("Controller may already be closed", { error });
177
+ }
178
+ frontendStreamControllerRef.current = null;
235
179
  };
236
180
  signal?.addEventListener("abort", abortHandler);
237
181
 
238
- sendPromptPromise
239
- .then(resolve)
240
- .catch(reject)
241
- .finally(() => {
242
- signal?.removeEventListener("abort", abortHandler);
243
- });
182
+ return () => {
183
+ signal?.removeEventListener("abort", abortHandler);
184
+ };
244
185
  },
245
- );
186
+ cancel() {
187
+ frontendStreamControllerRef.current = null;
188
+ },
189
+ });
246
190
 
247
- if (response === null) {
248
- Logger.error("Non-frontend-managed response is null", {
249
- response,
191
+ // Start the prompt, chunks will be sent via events
192
+ void props
193
+ .send_prompt({
194
+ messages: messages,
195
+ config: chatConfig,
196
+ })
197
+ .catch((error: Error) => {
198
+ frontendStreamControllerRef.current?.error(error);
199
+ frontendStreamControllerRef.current = null;
250
200
  });
251
- return new Response("Internal server error", { status: 500 });
252
- }
253
201
 
254
- // If streaming didn't happen (non-generator response), update the message
255
- // Check if streaming state is still set (meaning no chunks were received)
256
- if (
257
- streamingStateRef.current.backendMessageId === null &&
258
- streamingStateRef.current.frontendMessageIndex === null
259
- ) {
260
- setMessages((prev) => {
261
- const updated = [...prev];
262
- const index = updated.findIndex((m) => m.id === messageId);
263
- if (index !== -1) {
264
- updated[index] = {
265
- ...updated[index],
266
- parts: [{ type: "text", text: response }],
267
- };
268
- }
269
- return updated;
270
- });
271
- }
272
-
273
- return new Response(response);
274
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
275
- } catch (error: any) {
202
+ return createUIMessageStreamResponse({ stream });
203
+ } catch (error: unknown) {
276
204
  // Clear streaming state on error
277
205
  streamingStateRef.current = {
278
206
  backendMessageId: null,
@@ -280,13 +208,13 @@ export const Chatbot: React.FC<Props> = (props) => {
280
208
  };
281
209
 
282
210
  // Handle abort gracefully without showing an error
283
- if (error.name === "AbortError") {
211
+ if (error instanceof Error && error.name === "AbortError") {
284
212
  return new Response("Aborted", { status: 499 });
285
213
  }
286
214
 
287
215
  // HACK: strip the error message to clean up the response
288
- const strippedError = error.message
289
- .split("failed with exception ")
216
+ const strippedError = (error as Error).message
217
+ ?.split("failed with exception ")
290
218
  .pop();
291
219
  return new Response(strippedError, { status: 400 });
292
220
  }
@@ -307,11 +235,7 @@ export const Chatbot: React.FC<Props> = (props) => {
307
235
  frontendMessageIndex: null,
308
236
  };
309
237
 
310
- // For frontend-managed streaming, we set the value directly from the frontend.
311
- // Because useChat creates the proper message structure for us.
312
- if (props.frontendManaged) {
313
- props.setValue(message.messages);
314
- }
238
+ props.setValue(message.messages);
315
239
  },
316
240
  onError: (error) => {
317
241
  Logger.error("An error occurred:", error);
@@ -338,90 +262,28 @@ export const Chatbot: React.FC<Props> = (props) => {
338
262
  return;
339
263
  }
340
264
 
341
- if (props.frontendManaged) {
342
- // Push to the stream for useChat to process
343
- const controller = frontendStreamControllerRef.current;
344
- if (!controller) {
345
- return;
346
- }
347
-
348
- const frontendMessage = message as {
349
- type: string;
350
- message_id: string;
351
- content?: UIMessageChunk;
352
- is_final?: boolean;
353
- };
354
-
355
- if (frontendMessage.content) {
356
- controller.enqueue(frontendMessage.content);
357
- }
358
- if (frontendMessage.is_final) {
359
- controller.close();
360
- frontendStreamControllerRef.current = null;
361
- }
265
+ // Push to the stream for useChat to process
266
+ const controller = frontendStreamControllerRef.current;
267
+ if (!controller) {
362
268
  return;
363
269
  }
364
270
 
365
- // Handle regular text streaming chunks
366
- const chunkMessage = message as {
271
+ const frontendMessage = message as {
367
272
  type: string;
368
273
  message_id: string;
369
- content: string;
370
- is_final: boolean;
274
+ content?: UIMessageChunk;
275
+ is_final?: boolean;
371
276
  };
372
277
 
373
- // Initialize streaming state on first chunk if not already set
374
- if (streamingStateRef.current.backendMessageId === null) {
375
- // Find the last assistant message (which should be the placeholder we created)
376
- setMessages((prev) => {
377
- const updated = [...prev];
378
- // Find the last assistant message
379
- for (let i = updated.length - 1; i >= 0; i--) {
380
- if (updated[i].role === "assistant") {
381
- streamingStateRef.current = {
382
- backendMessageId: chunkMessage.message_id,
383
- frontendMessageIndex: i,
384
- };
385
- break;
386
- }
387
- }
388
- return updated;
389
- });
278
+ if (frontendMessage.content) {
279
+ controller.enqueue(frontendMessage.content);
390
280
  }
391
-
392
- // Only process chunks for the current streaming message
393
- const frontendIndex = streamingStateRef.current.frontendMessageIndex;
394
- if (
395
- streamingStateRef.current.backendMessageId ===
396
- chunkMessage.message_id &&
397
- frontendIndex !== null
398
- ) {
399
- setMessages((prev) => {
400
- const updated = [...prev];
401
- const index = frontendIndex;
402
-
403
- // Update the message at the tracked index
404
- if (index < updated.length) {
405
- const messageToUpdate = updated[index];
406
- if (messageToUpdate.role === "assistant") {
407
- updated[index] = {
408
- ...messageToUpdate,
409
- parts: [{ type: "text", text: chunkMessage.content }],
410
- };
411
- }
412
- }
413
-
414
- return updated;
415
- });
416
-
417
- // Clear streaming state when final chunk arrives
418
- if (chunkMessage.is_final) {
419
- streamingStateRef.current = {
420
- backendMessageId: null,
421
- frontendMessageIndex: null,
422
- };
423
- }
281
+ if (frontendMessage.is_final) {
282
+ controller.close();
283
+ frontendStreamControllerRef.current = null;
424
284
  }
285
+
286
+ return;
425
287
  },
426
288
  );
427
289
 
@@ -434,10 +296,7 @@ export const Chatbot: React.FC<Props> = (props) => {
434
296
  props.delete_chat_message({ index });
435
297
  setMessages(newMessages);
436
298
 
437
- // Since we manage the state in the frontend, we need to update the value.
438
- if (props.frontendManaged) {
439
- props.setValue(newMessages);
440
- }
299
+ props.setValue(newMessages);
441
300
  }
442
301
  };
443
302
 
@@ -526,7 +385,7 @@ export const Chatbot: React.FC<Props> = (props) => {
526
385
 
527
386
  return (
528
387
  <div
529
- key={message.id}
388
+ key={`${message.id}-${index}`}
530
389
  className={cn(
531
390
  "flex flex-col group gap-2",
532
391
  message.role === "user" ? "items-end" : "items-start",
@@ -8,18 +8,6 @@ export interface ChatMessage extends UIMessage {
8
8
  content: string | null; // Content is only added for backwards compatibility
9
9
  }
10
10
 
11
- export interface SendMessageRequest {
12
- messages: ChatMessage[];
13
- config: {
14
- max_tokens: number | null;
15
- temperature: number | null;
16
- top_p: number | null;
17
- top_k: number | null;
18
- frequency_penalty: number | null;
19
- presence_penalty: number | null;
20
- };
21
- }
22
-
23
11
  /**
24
12
  * These are snake_case because they come from the backend,
25
13
  * and are not modified when sent to the frontend.
@@ -32,3 +20,8 @@ export interface ChatConfig {
32
20
  frequency_penalty: number | null;
33
21
  presence_penalty: number | null;
34
22
  }
23
+
24
+ export interface SendMessageRequest {
25
+ messages: ChatMessage[];
26
+ config: ChatConfig;
27
+ }