@marimo-team/frontend 0.16.4 → 0.16.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (408) hide show
  1. package/dist/assets/{CellStatus-CEVFBnyt.js → CellStatus-BJRDATxe.js} +1 -1
  2. package/dist/assets/{ConnectedDataExplorerComponent-5izWKQVQ.js → ConnectedDataExplorerComponent-Cs4pQOKx.js} +1 -1
  3. package/dist/assets/{ImperativeModal-DujtmdOO.js → ImperativeModal-BG5LTpV0.js} +1 -1
  4. package/dist/assets/{JsonOutput-E2xVojk5.js → JsonOutput-BID8Oos7.js} +1 -1
  5. package/dist/assets/{LazyAnyLanguageCodeMirror-DHH4zj72.js → LazyAnyLanguageCodeMirror-RkzkO2YV.js} +2 -2
  6. package/dist/assets/MarimoErrorOutput-Lft73Wnl.js +6 -0
  7. package/dist/assets/{RenderHTML-BCi_V67U.js → RenderHTML-BoDLdBq-.js} +1 -1
  8. package/dist/assets/{VisuallyHidden-DvpnK2wO.js → VisuallyHidden-BiHw-PIc.js} +1 -1
  9. package/dist/assets/{accordion-C3CAEPwC.js → accordion-A41ffd5P.js} +1 -1
  10. package/dist/assets/{activity-BCW0BU81.js → activity-BhLNCNHF.js} +1 -1
  11. package/dist/assets/add-cell-with-ai-CxM_YKzf.js +36 -0
  12. package/dist/assets/{add-database-form-DSnHGqMe.js → add-database-form-Br1fMkMI.js} +1 -1
  13. package/dist/assets/{add-missing-import-Cwedhjm5.js → add-missing-import-CfRgNApn.js} +1 -1
  14. package/dist/assets/agent-panel-7ocujO8C.js +287 -0
  15. package/dist/assets/ai-model-dropdown-DSUVFIso.js +2 -0
  16. package/dist/assets/{alert-dialog-M1dUQe7C.js → alert-dialog-BO8sf-73.js} +1 -1
  17. package/dist/assets/{ansi_up-ZmFuCItK.js → ansi_up-D_b0GS7N.js} +1 -1
  18. package/dist/assets/{any-language-editor-BqGBgxZE.js → any-language-editor-edee1A1P.js} +1 -1
  19. package/dist/assets/app-config-button-Bg_CEfls.js +1 -0
  20. package/dist/assets/{architecture-O4VJ6CD3-CbkBEQri.js → architecture-O4VJ6CD3-CIYFBxkI.js} +1 -1
  21. package/dist/assets/{architectureDiagram-W76B3OCA-di95lJcF.js → architectureDiagram-W76B3OCA-CXqAkVTy.js} +1 -1
  22. package/dist/assets/{arrow-left-DQ-94PlS.js → arrow-left-D97p491f.js} +1 -1
  23. package/dist/assets/{between-horizontal-start-CotWLlFt.js → between-horizontal-start-DWTOsiF_.js} +1 -1
  24. package/dist/assets/{blockDiagram-QIGZ2CNN-ClcJSQFf.js → blockDiagram-QIGZ2CNN-DhYrUig_.js} +1 -1
  25. package/dist/assets/{c4Diagram-FPNF74CW-Cq2vxSdy.js → c4Diagram-FPNF74CW-Bj1S_Fyy.js} +1 -1
  26. package/dist/assets/{cell-actions-C5S4W3g_.js → cell-actions-hNx4EMmZ.js} +1 -1
  27. package/dist/assets/{cell-editor-X6EY7GQl.js → cell-editor-JimG_bBz.js} +13 -13
  28. package/dist/assets/cell-link-_kF38gGF.js +1 -0
  29. package/dist/assets/{cells-B4cnsYe_.js → cells-Dd1FatlG.js} +54 -54
  30. package/dist/assets/channel-Bil_pUlM.js +1 -0
  31. package/dist/assets/{chart-no-axes-column-DrG7h8mS.js → chart-no-axes-column-DmR44Tbq.js} +1 -1
  32. package/dist/assets/{chat-components-DXkntpg4.js → chat-components-OoNU4tLf.js} +3 -3
  33. package/dist/assets/chat-panel-DatwRFif.js +3 -0
  34. package/dist/assets/check-C5PVLNkJ.js +1 -0
  35. package/dist/assets/{chevron-right-Caf5yL5B.js → chevron-right-BDEhimQq.js} +1 -1
  36. package/dist/assets/{chunk-3AY6CYHV-BFFUJATX.js → chunk-3AY6CYHV-CBq2x1Nc.js} +1 -1
  37. package/dist/assets/{chunk-4KMFLZZN-D8J8fzqf.js → chunk-4KMFLZZN-DEMg9QYp.js} +1 -1
  38. package/dist/assets/{chunk-6OXUPJBA-Clo7-gS4.js → chunk-6OXUPJBA-CjFdZBrY.js} +2 -2
  39. package/dist/assets/{chunk-ABZYJK2D-DjRcbxmx.js → chunk-ABZYJK2D-eZsthrBr.js} +1 -1
  40. package/dist/assets/{chunk-BN7GFLIU-DvomLhVN.js → chunk-BN7GFLIU-ez-vZ7uD.js} +1 -1
  41. package/dist/assets/{chunk-CXMOBAN2-GhUPxuLT.js → chunk-CXMOBAN2-DxbPW6zT.js} +1 -1
  42. package/dist/assets/{chunk-EXTU4WIE-97Zvkznr.js → chunk-EXTU4WIE-C8Y_P6y8.js} +1 -1
  43. package/dist/assets/{chunk-JA3XYJ7Z-Mvfz9vG6.js → chunk-JA3XYJ7Z-pR89xWsn.js} +1 -1
  44. package/dist/assets/{chunk-JEIROHC2-Cp1tR_z8.js → chunk-JEIROHC2-2-ucCTVJ.js} +1 -1
  45. package/dist/assets/{chunk-K7UQS3LO-BbFs0Y5e.js → chunk-K7UQS3LO-Bz3bjON2.js} +1 -1
  46. package/dist/assets/{chunk-KMC2YHZD-Buiqyl2g.js → chunk-KMC2YHZD-BvMr39QE.js} +1 -1
  47. package/dist/assets/{chunk-QN33PNHL-dhs223oU.js → chunk-QN33PNHL-DgF0LOHR.js} +1 -1
  48. package/dist/assets/{chunk-QYVHNE3D-DA_jYaIp.js → chunk-QYVHNE3D-BxN3DJBX.js} +1 -1
  49. package/dist/assets/{chunk-S3R3BYOJ-DO68jEIo.js → chunk-S3R3BYOJ-Dy72CLbv.js} +1 -1
  50. package/dist/assets/{chunk-T44TD3VJ-Ww2OhwR5.js → chunk-T44TD3VJ-BfMjD4hS.js} +1 -1
  51. package/dist/assets/{chunk-TVAH2DTR-j2EljfwG.js → chunk-TVAH2DTR-CKnRAcjo.js} +1 -1
  52. package/dist/assets/{chunk-TZMSLE5B-DYFKU4Pb.js → chunk-TZMSLE5B-DdgcuCwZ.js} +1 -1
  53. package/dist/assets/{chunk-WFRQ32O7-k2LaZwie.js → chunk-WFRQ32O7-CHVQx4E8.js} +1 -1
  54. package/dist/assets/{chunk-WFWHJNB7-h5yM_3qQ.js → chunk-WFWHJNB7-B095GDsj.js} +1 -1
  55. package/dist/assets/{chunk-XRWGC2XP-C9Mh6qts.js → chunk-XRWGC2XP-C9u0mhR4.js} +1 -1
  56. package/dist/assets/{circle-play-Cktn64O2.js → circle-play-BnvyuDgL.js} +1 -1
  57. package/dist/assets/{circle-plus-CR5IX63e.js → circle-plus-CfdbDkkn.js} +1 -1
  58. package/dist/assets/{circle-x-t3DIkXqJ.js → circle-x-BsVcxKkV.js} +1 -1
  59. package/dist/assets/classDiagram-KNZD7YFC-CjqRV-TB.js +1 -0
  60. package/dist/assets/classDiagram-v2-RKCZMP56-CGekJfCg.js +1 -0
  61. package/dist/assets/client-RNr6mM1Y.js +2 -0
  62. package/dist/assets/{clipboard-paste-CCXUHJEo.js → clipboard-paste-CYFMW3x7.js} +1 -1
  63. package/dist/assets/column-preview-2H8pwalb.js +2 -0
  64. package/dist/assets/{columns-BBxos2iF.js → columns-qXe5bccO.js} +7 -7
  65. package/dist/assets/{command-CMralWVx.js → command-BZVf1cJP.js} +1 -1
  66. package/dist/assets/command-palette-CYMxp9xF.js +1 -0
  67. package/dist/assets/{common-CGhyb0HV.js → common-DW3bNKWY.js} +1 -1
  68. package/dist/assets/{config-DiCy6eC0.js → config-DXGmIv9f.js} +1 -1
  69. package/dist/assets/{copy-DAVB02c8.js → copy-6mpL4BeI.js} +1 -1
  70. package/dist/assets/{copy-icon-GGPHJWJ0.js → copy-icon-6ICckC-p.js} +1 -1
  71. package/dist/assets/{dagre-5GWH7T2D-B1wEBSrx.js → dagre-5GWH7T2D-hVCok2au.js} +1 -1
  72. package/dist/assets/{data-grid-overlay-editor-Drp4I0tg.js → data-grid-overlay-editor-BwcAr1JM.js} +1 -1
  73. package/dist/assets/datasources-panel-BvrtAadm.js +1 -0
  74. package/dist/assets/{dates-grtSI02N.js → dates-Au76svwW.js} +1 -1
  75. package/dist/assets/dependency-graph-panel-F9AD_whb.js +4 -0
  76. package/dist/assets/{diagram-N5W7TBWH-D0MGIq61.js → diagram-N5W7TBWH-C26XpepA.js} +1 -1
  77. package/dist/assets/{diagram-QEK2KX5R-DU6geLeA.js → diagram-QEK2KX5R-yrTR8I_L.js} +1 -1
  78. package/dist/assets/{diagram-S2PKOQOG-BNhY4Z1-.js → diagram-S2PKOQOG-BnrvSrEb.js} +1 -1
  79. package/dist/assets/{dialog-B7icy1Vb.js → dialog-CR68_CUl.js} +1 -1
  80. package/dist/assets/{dist-BNjtn4W8.js → dist--01dzFeG.js} +1 -1
  81. package/dist/assets/{dist-BagyUivg.js → dist--UHY1FN-.js} +1 -1
  82. package/dist/assets/{dist-5Gm6w_15.js → dist-6vTAXnMq.js} +1 -1
  83. package/dist/assets/{dist-DTazGMur.js → dist-B6CCfKkp.js} +1 -1
  84. package/dist/assets/dist-BAqgWgpM.js +1 -0
  85. package/dist/assets/{dist-BaApG_tl.js → dist-BUe_o-3o.js} +1 -1
  86. package/dist/assets/{dist-BpAb8rGb.js → dist-BnTbfmCK.js} +1 -1
  87. package/dist/assets/dist-C-4GTx-T.js +1 -0
  88. package/dist/assets/{dist-C0ek66tJ.js → dist-C1lnVyyK.js} +1 -1
  89. package/dist/assets/{dist-DGiVfc7V.js → dist-CbsJnssA.js} +1 -1
  90. package/dist/assets/{dist-DV-8bxFo.js → dist-CjoeBoZ9.js} +1 -1
  91. package/dist/assets/{dist-D5QvSsL_.js → dist-CsC8ZokE.js} +1 -1
  92. package/dist/assets/{dist-C69eWtaQ.js → dist-CyqTsfyg.js} +1 -1
  93. package/dist/assets/dist-D-ZYdf69.js +1 -0
  94. package/dist/assets/dist-D3B_GqVR.js +1 -0
  95. package/dist/assets/{dist-BME02X12.js → dist-DFJwMM7Z.js} +1 -1
  96. package/dist/assets/dist-Db9UVaw9.js +1 -0
  97. package/dist/assets/{dist-BPr57Wxb.js → dist-DhXqYYeD.js} +1 -1
  98. package/dist/assets/{dist-CL0hPMY6.js → dist-Dm8m1boP.js} +1 -1
  99. package/dist/assets/{dist-B0vg88Aq.js → dist-DvDyxv8b.js} +1 -1
  100. package/dist/assets/{dist-Bzn1Zd0x.js → dist-DzUKODTF.js} +1 -1
  101. package/dist/assets/dist-LmEq3o4w.js +1 -0
  102. package/dist/assets/dist-Z_cK0cSh.js +1 -0
  103. package/dist/assets/dist-biP83Yvc.js +1 -0
  104. package/dist/assets/dist-dJ4FqqTe.js +1 -0
  105. package/dist/assets/{documentation-panel-D4iq1tSm.js → documentation-panel-DYKAf6Sg.js} +1 -1
  106. package/dist/assets/{dom-4KyFHEbl.js → dom-CT3dAMQW.js} +1 -1
  107. package/dist/assets/{download-C4Fyu6kU.js → download-B4_BX7gi.js} +1 -1
  108. package/dist/assets/{download-qt61TbgC.js → download-BB5Iexmn.js} +1 -1
  109. package/dist/assets/{dropdown-menu-Bp1vhqcS.js → dropdown-menu-CJDB1PNI.js} +1 -1
  110. package/dist/assets/edit-page-BK3Irdme.js +12 -0
  111. package/dist/assets/{ellipsis-DVXWk8Lc.js → ellipsis-CJtiw1k3.js} +1 -1
  112. package/dist/assets/{ellipsis-vertical-DfpheMuY.js → ellipsis-vertical-DK--y082.js} +1 -1
  113. package/dist/assets/{en-US-B2g9dciI.js → en-US-CjWuOpsV.js} +1 -1
  114. package/dist/assets/{erDiagram-AWTI2OKA-DxxWZrYD.js → erDiagram-AWTI2OKA-9EqwLrlG.js} +1 -1
  115. package/dist/assets/{error-banner-ARu6PiHL.js → error-banner-BGjnZePp.js} +1 -1
  116. package/dist/assets/error-panel-CrkbkIF_.js +1 -0
  117. package/dist/assets/{es-C0Ih1AxE.js → es-C-CWIA-E.js} +1 -1
  118. package/dist/assets/{esm-BR7TuyMc.js → esm-7XxuulnL.js} +1 -1
  119. package/dist/assets/{esm-Cb-iIF_w.js → esm-B39og2OG.js} +1 -1
  120. package/dist/assets/{esm-BIF8NHm8.js → esm-BBn_y9Ew.js} +1 -1
  121. package/dist/assets/esm-DjUQOOJ2.js +1 -0
  122. package/dist/assets/{eye-off-BEVibdMQ.js → eye-off-9UMe_Y7D.js} +1 -1
  123. package/dist/assets/field-D6g5A_wf.js +1 -0
  124. package/dist/assets/{file-DqkkCGhs.js → file-BENStGHx.js} +1 -1
  125. package/dist/assets/file-explorer-panel-Cgv3WjVh.js +1 -0
  126. package/dist/assets/{file-plus-2-BCmZgbYs.js → file-plus-2-CloHhbsF.js} +1 -1
  127. package/dist/assets/{file-text-DNmaotaP.js → file-text-Lr1kJd4E.js} +1 -1
  128. package/dist/assets/{file-video-camera-C5lALvNf.js → file-video-camera-CfnyBQQe.js} +1 -1
  129. package/dist/assets/filename-B5Yo1bOu.js +1 -0
  130. package/dist/assets/{floating-outline-Cjas_exC.js → floating-outline-DZnSnZfg.js} +1 -1
  131. package/dist/assets/{flowDiagram-PVAE7QVJ-DlTZtqcN.js → flowDiagram-PVAE7QVJ-iOj6Qgu-.js} +1 -1
  132. package/dist/assets/{focus-OWoLlKnm.js → focus-Bnk25hTp.js} +1 -1
  133. package/dist/assets/{form-xOqp67zT.js → form-BGZvwlog.js} +1 -1
  134. package/dist/assets/{form--nX5W3gQ.js → form-DyKYT1WR.js} +1 -1
  135. package/dist/assets/{formats-C8bbggqj.js → formats-CWdWXhfT.js} +1 -1
  136. package/dist/assets/{fullscreen-BFmvQx5m.js → fullscreen-DTPr3iBY.js} +1 -1
  137. package/dist/assets/{ganttDiagram-OWAHRB6G-BEPmawB5.js → ganttDiagram-OWAHRB6G-BWbXeAXa.js} +1 -1
  138. package/dist/assets/{gitGraph-ZV4HHKMB-DsmmnKI3.js → gitGraph-ZV4HHKMB-BpeeuO4L.js} +1 -1
  139. package/dist/assets/{gitGraphDiagram-NY62KEGX-DfTKmX9v.js → gitGraphDiagram-NY62KEGX-BX3O-mzY.js} +1 -1
  140. package/dist/assets/{glide-data-editor-CzDe-oK3.js → glide-data-editor-C45ArX7n.js} +4 -4
  141. package/dist/assets/globals-BFoVgbHf.js +1 -0
  142. package/dist/assets/{globe-CgG1jfYF.js → globe-CPrVx8HM.js} +1 -1
  143. package/dist/assets/home-page-DhT6cm6c.js +4 -0
  144. package/dist/assets/{image-DXGqie4b.js → image-DTv0Ic6H.js} +1 -1
  145. package/dist/assets/{index-DtggTI4O.js → index-29P5xX8u.js} +11 -11
  146. package/dist/assets/index-Optxbl37.css +2 -0
  147. package/dist/assets/{info-63CPKGFF-BVRAJzgS.js → info-63CPKGFF-Czr08O9A.js} +1 -1
  148. package/dist/assets/{infoDiagram-STP46IZ2-CcEqfhrj.js → infoDiagram-STP46IZ2-C1JX9JfB.js} +1 -1
  149. package/dist/assets/input-C1RzjWSK.js +7 -0
  150. package/dist/assets/{isValid-gOtpcPxn.js → isValid-o3nZVu8e.js} +1 -1
  151. package/dist/assets/{journeyDiagram-BIP6EPQ6-CfxDuLls.js → journeyDiagram-BIP6EPQ6-CC2JvTQD.js} +1 -1
  152. package/dist/assets/{kanban-definition-6OIFK2YF-BwopERfW.js → kanban-definition-6OIFK2YF-3qAhCi66.js} +1 -1
  153. package/dist/assets/{key-BuxNhFKW.js → key-D4QiH_7H.js} +1 -1
  154. package/dist/assets/{kiosk-mode--OX2RHZj.js → kiosk-mode-Dy2WnuWt.js} +1 -1
  155. package/dist/assets/{label-COeaBwl_.js → label-BEUjZsdo.js} +1 -1
  156. package/dist/assets/{layout-CKoMTVJt.js → layout-C6K0XXFK.js} +3 -3
  157. package/dist/assets/{linear-BI0LBATm.js → linear-nWRf49aw.js} +1 -1
  158. package/dist/assets/{link-DSY8ADga.js → link-CDOxp9sn.js} +1 -1
  159. package/dist/assets/links-D-L0rzz9.js +1 -0
  160. package/dist/assets/{list-filter-D2Wx3thV.js → list-filter-CRC72QPW.js} +1 -1
  161. package/dist/assets/{loader-CPDA0quD.js → loader-CgbiPC_T.js} +1 -1
  162. package/dist/assets/logs-panel-BB-6orqg.js +1 -0
  163. package/dist/assets/{maps-CxCIYhRT.js → maps-DaQbs_UR.js} +1 -1
  164. package/dist/assets/{menu-items-COILZQ4q.js → menu-items-Bo6Dyd_Q.js} +1 -1
  165. package/dist/assets/{mermaid-oqJ6vLFm.js → mermaid-Bqzxmx0C.js} +1 -1
  166. package/dist/assets/{mermaid-parser.core-8414a7OP.js → mermaid-parser.core-CwRCqiGJ.js} +2 -2
  167. package/dist/assets/{mermaid.core-CKfX2q8j.js → mermaid.core-C4o4vdkw.js} +3 -3
  168. package/dist/assets/mermaid.core-DjncFP_O.js +1 -0
  169. package/dist/assets/{mindmap-definition-Q6HEUPPD-nadsjaMC.js → mindmap-definition-Q6HEUPPD-pLcSm-bI.js} +1 -1
  170. package/dist/assets/{mode-CBh2Ag_Y.js → mode-DQPKc-Hp.js} +1 -1
  171. package/dist/assets/{name-cell-input-CAG50xh2.js → name-cell-input-DQd65hJw.js} +1 -1
  172. package/dist/assets/{number-overlay-editor-CbWBjwI1.js → number-overlay-editor-Ce_FEpnn.js} +1 -1
  173. package/dist/assets/once-8ZDiGGtA.js +1 -0
  174. package/dist/assets/outline-panel-BJDiYH61.js +1 -0
  175. package/dist/assets/packages-panel-D_VswrEd.js +1 -0
  176. package/dist/assets/{packet-HUATNLJX-BJ_b_gYi.js → packet-HUATNLJX-C5NsAS_7.js} +1 -1
  177. package/dist/assets/{pie-WTHONI2E-CS2JfH5S.js → pie-WTHONI2E-BCNGQ0_9.js} +1 -1
  178. package/dist/assets/{pieDiagram-ADFJNKIX-DP_lAtPz.js → pieDiagram-ADFJNKIX-CUCBn1VN.js} +1 -1
  179. package/dist/assets/plug-DrNpofTj.js +1 -0
  180. package/dist/assets/{plus-C1zexBxS.js → plus-d2HNOuZI.js} +1 -1
  181. package/dist/assets/{popover-CLp_lH16.js → popover-DW0D4l0O.js} +1 -1
  182. package/dist/assets/{precisionRound-CR2cxaaR.js → precisionRound-TxjBk8nN.js} +1 -1
  183. package/dist/assets/{quadrantDiagram-LMRXKWRM-gzT_-w3S.js → quadrantDiagram-LMRXKWRM-C6DXTSnZ.js} +1 -1
  184. package/dist/assets/{radar-NJJJXTRR-ChMDxgqR.js → radar-NJJJXTRR-Cck-wBOB.js} +1 -1
  185. package/dist/assets/{react-plotly-DUuIpNDT.js → react-plotly-x7-8ig7L.js} +1 -1
  186. package/dist/assets/{readonly-python-code-DMLMHG1v.js → readonly-python-code-Cb7Ak_Dy.js} +1 -1
  187. package/dist/assets/{refresh-ccw-lUiAEOAx.js → refresh-ccw-CCJeTTJO.js} +1 -1
  188. package/dist/assets/{refresh-cw-CSv3xyYY.js → refresh-cw-B_tmnHav.js} +1 -1
  189. package/dist/assets/{renderShortcut-DMYtt-ju.js → renderShortcut-C9_NT6sD.js} +1 -1
  190. package/dist/assets/{request-registry-4Bq310sk.js → request-registry-D4PD0fDJ.js} +1 -1
  191. package/dist/assets/{requirementDiagram-4UW4RH46-aavD0qQF.js → requirementDiagram-4UW4RH46-Bj7w3axz.js} +1 -1
  192. package/dist/assets/run-page-D9jntYU0.js +1 -0
  193. package/dist/assets/{runs-CItfCHkl.js → runs-BWcKkv9g.js} +1 -1
  194. package/dist/assets/{sankeyDiagram-GR3RE2ED-r95m_h3N.js → sankeyDiagram-GR3RE2ED-DCmlCkUu.js} +1 -1
  195. package/dist/assets/{save-Bg0tsaXV.js → save-CVcbYdvl.js} +1 -1
  196. package/dist/assets/scratchpad-panel-BUGlPLwQ.js +1 -0
  197. package/dist/assets/{scroll-text-SAt1GCBr.js → scroll-text-CN-2fr92.js} +1 -1
  198. package/dist/assets/secrets-panel-DGPyMcTb.js +1 -0
  199. package/dist/assets/{select-CMG6DC3j.js → select-DKRTzlUU.js} +1 -1
  200. package/dist/assets/{send-ePQN2mpH.js → send-DRRBOpzT.js} +1 -1
  201. package/dist/assets/{sequenceDiagram-C3RYC4MD-C4GqHIgf.js → sequenceDiagram-C3RYC4MD-CtIOF8jj.js} +1 -1
  202. package/dist/assets/{settings-TIv8aSog.js → settings-6ySBJQ7Y.js} +1 -1
  203. package/dist/assets/{share-CUbi0XlA.js → share-Dcl7D_tA.js} +1 -1
  204. package/dist/assets/snippets-panel-CKi40HiX.js +1 -0
  205. package/dist/assets/{spinner-CxlO4-GJ.js → spinner-BhnfQOEl.js} +1 -1
  206. package/dist/assets/{square-uM1ci7iL.js → square-DKPXnMmD.js} +1 -1
  207. package/dist/assets/{square-function-OflPQrBg.js → square-function-DBJINsmk.js} +1 -1
  208. package/dist/assets/{square-terminal-DZAwMMdQ.js → square-terminal-DoFRZ-M6.js} +1 -1
  209. package/dist/assets/{src-BOK-SWX4.js → src-KuQao6GK.js} +1 -1
  210. package/dist/assets/state-B37sZn4X.js +1 -0
  211. package/dist/assets/{state-COfuW2QS.js → state-CEmS5WFQ.js} +1 -1
  212. package/dist/assets/state-jvUYiWCG.js +1 -0
  213. package/dist/assets/{stateDiagram-KXAO66HF-CdN43FzO.js → stateDiagram-KXAO66HF-DwZscOce.js} +1 -1
  214. package/dist/assets/stateDiagram-v2-UMBNRL4Z-D5XUGcJP.js +1 -0
  215. package/dist/assets/stex-C7nwqmPk.js +1 -0
  216. package/dist/assets/storage-CaQ7kwuv.js +1 -0
  217. package/dist/assets/{switch-BKaPFRvh.js → switch-B5bMMWJn.js} +1 -1
  218. package/dist/assets/{tabs-C8HicIPZ.js → tabs-8ThyQfYh.js} +1 -1
  219. package/dist/assets/{terminal-Cnm8ANjQ.js → terminal-CPdYItDn.js} +1 -1
  220. package/dist/assets/{text-search-DpMeajoz.js → text-search-iEvFn29l.js} +1 -1
  221. package/dist/assets/{textarea-DhU2DWSB.js → textarea-B-_OthMe.js} +1 -1
  222. package/dist/assets/{time-Dzg4b75Q.js → time-BkIHCvH2.js} +1 -1
  223. package/dist/assets/{timeline-definition-XQNQX7LJ-D48ppGT8.js → timeline-definition-XQNQX7LJ-BGsZ09p6.js} +1 -1
  224. package/dist/assets/{toDate-BartytS4.js → toDate-Daj1hQSF.js} +1 -1
  225. package/dist/assets/{toggle-BLLoLiay.js → toggle-BpFqu8FB.js} +1 -1
  226. package/dist/assets/{tooltip-BjoMzmCN.js → tooltip-ULHbIsj9.js} +1 -1
  227. package/dist/assets/tracing-UKZUjbDB.js +2 -0
  228. package/dist/assets/tracing-panel-CuDItRLt.js +2 -0
  229. package/dist/assets/{trash-2-GOPu47oc.js → trash-2-3UJSaMKF.js} +1 -1
  230. package/dist/assets/{trash-BpVsWH8l.js → trash-CYX7fe5Y.js} +1 -1
  231. package/dist/assets/{tree-qyAlDlFy.js → tree-3z9r1N_5.js} +1 -1
  232. package/dist/assets/{treemap-75Q7IDZK-B4o24kyC.js → treemap-75Q7IDZK-MX1Hmq0m.js} +1 -1
  233. package/dist/assets/{type-C9leWRlU.js → type-kF6pOJbH.js} +1 -1
  234. package/dist/assets/{types-BBD3GQ0S.js → types-DQDL7dro.js} +1 -1
  235. package/dist/assets/{types-DEwRoAG0.js → types-DyTIgBnH.js} +1 -1
  236. package/dist/assets/{useAddCell-DJhNA_O5.js → useAddCell-Dq3HqYz1.js} +1 -1
  237. package/dist/assets/{useAsyncData-BEqqunls.js → useAsyncData-D9GA9BWg.js} +1 -1
  238. package/dist/assets/{useBoolean-DnggoYme.js → useBoolean-CSR3XjhE.js} +1 -1
  239. package/dist/assets/{useCellActionButton-B_a4Sv2X.js → useCellActionButton-BAG0Vvnt.js} +1 -1
  240. package/dist/assets/{useDateFormatter-DjmrLzxH.js → useDateFormatter-DrFLqO1D.js} +1 -1
  241. package/dist/assets/{useDebounce-9_rqRiHk.js → useDebounce-_ztZiL0I.js} +1 -1
  242. package/dist/assets/{useDeepCompareMemoize-DIhr42Iz.js → useDeepCompareMemoize-BsZY8i2r.js} +1 -1
  243. package/dist/assets/{useDeleteCell-DVNOLjwN.js → useDeleteCell-CJaipocw.js} +1 -1
  244. package/dist/assets/useHotkey-DkiyGPLs.js +1 -0
  245. package/dist/assets/{useInstallPackage-CTHO3tj3.js → useInstallPackage-DoKAq17E.js} +1 -1
  246. package/dist/assets/useNotebookActions-CQd8IgyR.js +1 -0
  247. package/dist/assets/useSplitCell-Dodncnp8.js +1 -0
  248. package/dist/assets/{useTheme-C5JyqXTm.js → useTheme-oPMxEKRc.js} +1 -1
  249. package/dist/assets/{utilities.esm-DbqS7Pjb.js → utilities.esm-DcV_e-D3.js} +1 -1
  250. package/dist/assets/utils-DBmmAf_K.js +1 -0
  251. package/dist/assets/variable-panel-BCihDsBL.js +1 -0
  252. package/dist/assets/{vega-component-D1ZJxK-L.js → vega-component-CWMEFM7y.js} +1 -1
  253. package/dist/assets/{vega-loader.browser.module-Jwd7L8Ye.js → vega-loader.browser.module-BkWiTok0.js} +1 -1
  254. package/dist/assets/{with-selector-CXhuorCH.js → with-selector-BmLsipPw.js} +1 -1
  255. package/dist/assets/{workflow-Covue_dW.js → workflow-DA01FBLw.js} +1 -1
  256. package/dist/assets/{wrench-DNJq8NCj.js → wrench-B2m2X1sb.js} +1 -1
  257. package/dist/assets/{write-secret-modal-qe46KOIw.js → write-secret-modal-Dx9oubag.js} +1 -1
  258. package/dist/assets/{xychartDiagram-6GGTOJPD-DK41sZTI.js → xychartDiagram-6GGTOJPD-D-i5LTeX.js} +1 -1
  259. package/dist/assets/{youtube-0-RiaVkr.js → youtube-Bl4NeyvA.js} +1 -1
  260. package/dist/index.html +155 -155
  261. package/package.json +1 -1
  262. package/src/__tests__/chat-history.test.ts +123 -0
  263. package/src/components/app-config/ai-config.tsx +23 -0
  264. package/src/components/app-config/mcp-config.tsx +42 -2
  265. package/src/components/app-config/user-config-form.tsx +0 -24
  266. package/src/components/chat/acp/__tests__/context-utils.test.ts +1 -1
  267. package/src/components/chat/acp/agent-panel.tsx +1 -1
  268. package/src/components/chat/acp/blocks.tsx +46 -53
  269. package/src/components/chat/acp/common.tsx +1 -1
  270. package/src/components/chat/acp/context-utils.ts +1 -1
  271. package/src/components/chat/acp/session-tabs.tsx +1 -1
  272. package/src/components/chat/chat-history-popover.tsx +125 -0
  273. package/src/components/chat/chat-history-utils.ts +69 -0
  274. package/src/components/chat/chat-panel.tsx +9 -57
  275. package/src/components/editor/__tests__/data-attributes.test.tsx +1 -1
  276. package/src/components/editor/actions/useNotebookActions.tsx +2 -4
  277. package/src/components/editor/ai/__tests__/completion-utils.test.ts +23 -31
  278. package/src/components/editor/cell/CreateCellButton.tsx +14 -2
  279. package/src/components/editor/cell/code/cell-editor.tsx +1 -0
  280. package/src/components/editor/database/schemas.ts +2 -10
  281. package/src/components/editor/{Cell.tsx → notebook-cell.tsx} +5 -1
  282. package/src/components/editor/output/MarimoErrorOutput.tsx +4 -34
  283. package/src/components/editor/renderers/{CellArray.tsx → cell-array.tsx} +1 -1
  284. package/src/components/forms/__tests__/form-utils.test.ts +2 -2
  285. package/src/components/mcp/hooks.ts +48 -0
  286. package/src/components/mcp/mcp-status-indicator.tsx +144 -0
  287. package/src/components/ui/number-field.tsx +4 -1
  288. package/src/core/ai/context/providers/__tests__/__snapshots__/tables.test.ts.snap +13 -19
  289. package/src/core/ai/context/providers/__tests__/cell-output.test.ts +0 -1
  290. package/src/core/ai/context/providers/__tests__/datasource.test.ts +5 -6
  291. package/src/core/ai/context/providers/__tests__/error.test.ts +24 -15
  292. package/src/core/ai/context/providers/cell-output.ts +5 -5
  293. package/src/core/ai/context/providers/common.ts +13 -4
  294. package/src/core/ai/context/providers/datasource.ts +31 -20
  295. package/src/core/ai/context/providers/error.ts +3 -4
  296. package/src/core/ai/context/providers/file.ts +2 -2
  297. package/src/core/ai/context/providers/tables.ts +36 -8
  298. package/src/core/ai/context/providers/variable.ts +2 -3
  299. package/src/core/cells/__tests__/cells.test.ts +6 -6
  300. package/src/core/cells/cells.ts +12 -13
  301. package/src/core/cells/scrollCellIntoView.ts +1 -1
  302. package/src/core/codemirror/__tests__/setup.test.ts +1 -0
  303. package/src/core/codemirror/cm.ts +3 -2
  304. package/src/core/config/__tests__/config-schema.test.ts +2 -0
  305. package/src/core/config/config-schema.ts +2 -0
  306. package/src/core/config/feature-flag.tsx +0 -2
  307. package/src/core/edit-app.tsx +1 -1
  308. package/src/core/network/CachingRequestRegistry.ts +2 -2
  309. package/src/stories/cell.stories.tsx +1 -1
  310. package/src/stories/layout/vertical/one-column.stories.tsx +1 -1
  311. package/src/utils/numbers.ts +24 -1
  312. package/dist/assets/MarimoErrorOutput-CUb4AQdT.js +0 -6
  313. package/dist/assets/add-cell-with-ai-DCyfgnLI.js +0 -36
  314. package/dist/assets/agent-panel-B_MMb9mo.js +0 -287
  315. package/dist/assets/ai-model-dropdown-Dk9Kz_pz.js +0 -2
  316. package/dist/assets/api-DBBaApVO.js +0 -1
  317. package/dist/assets/app-config-button-Cbw9b5rl.js +0 -1
  318. package/dist/assets/cell-link-woRE950-.js +0 -1
  319. package/dist/assets/channel-D-YgrD6I.js +0 -1
  320. package/dist/assets/chat-panel-DLphumiN.js +0 -3
  321. package/dist/assets/check-hL6-9SZK.js +0 -1
  322. package/dist/assets/circle-check-big-C7DGeh12.js +0 -1
  323. package/dist/assets/classDiagram-KNZD7YFC-yzXw7kFX.js +0 -1
  324. package/dist/assets/classDiagram-v2-RKCZMP56-Co2zbBi0.js +0 -1
  325. package/dist/assets/client-CA946N69.js +0 -2
  326. package/dist/assets/column-preview-BT14RHNM.js +0 -2
  327. package/dist/assets/command-palette-qYrNUNjA.js +0 -1
  328. package/dist/assets/datasources-panel-2YJ76Lq8.js +0 -1
  329. package/dist/assets/dependency-graph-panel-CnzvmPdT.js +0 -4
  330. package/dist/assets/dist-BtRvVXgu.js +0 -1
  331. package/dist/assets/dist-CAZ5kHnb.js +0 -1
  332. package/dist/assets/dist-CN8IvtVY.js +0 -1
  333. package/dist/assets/dist-Cw007UHk.js +0 -1
  334. package/dist/assets/dist-DEfSR7VW.js +0 -1
  335. package/dist/assets/dist-DSbiMNpu.js +0 -1
  336. package/dist/assets/dist-DeIZvG9x.js +0 -1
  337. package/dist/assets/dist-DyZWkD0n.js +0 -1
  338. package/dist/assets/dist-hfODPqg9.js +0 -1
  339. package/dist/assets/edit-page-Bt_YqRld.js +0 -12
  340. package/dist/assets/error-panel-dvBEznKE.js +0 -1
  341. package/dist/assets/esm-hOS9Yf3s.js +0 -1
  342. package/dist/assets/field-Ota1KKvP.js +0 -1
  343. package/dist/assets/file-explorer-panel-Pa89UfV1.js +0 -1
  344. package/dist/assets/filename-BYm5Do9U.js +0 -1
  345. package/dist/assets/home-page-B3bIZC6F.js +0 -4
  346. package/dist/assets/index-BQd14tU4.css +0 -2
  347. package/dist/assets/input-Dm-m3XYB.js +0 -7
  348. package/dist/assets/links-CQoApRoA.js +0 -1
  349. package/dist/assets/logs-panel-R50NxjC7.js +0 -1
  350. package/dist/assets/mermaid.core-BjBlUxCx.js +0 -1
  351. package/dist/assets/numbers-DtHKLeOn.js +0 -1
  352. package/dist/assets/outline-panel-CB2kV_p5.js +0 -1
  353. package/dist/assets/packages-panel-BpFuUbAr.js +0 -1
  354. package/dist/assets/run-page-ClDuCh42.js +0 -1
  355. package/dist/assets/scratchpad-panel-BRljth0m.js +0 -1
  356. package/dist/assets/secrets-panel-CQON2dfx.js +0 -1
  357. package/dist/assets/snippets-panel-C0OdhmTA.js +0 -1
  358. package/dist/assets/state-DaDgAzck.js +0 -1
  359. package/dist/assets/state-Do6Fn2Io.js +0 -1
  360. package/dist/assets/stateDiagram-v2-UMBNRL4Z-Bi0DZGHg.js +0 -1
  361. package/dist/assets/stex-CbLDtSMU.js +0 -1
  362. package/dist/assets/storage-DFOl3UlZ.js +0 -1
  363. package/dist/assets/tracing-k1M6Upka.js +0 -2
  364. package/dist/assets/tracing-panel-CyG4yTCu.js +0 -2
  365. package/dist/assets/useHotkey-CJ5v8JMM.js +0 -1
  366. package/dist/assets/useNotebookActions-BB-5-4dL.js +0 -1
  367. package/dist/assets/useSplitCell-Cy53n7mS.js +0 -1
  368. package/dist/assets/utils-CfnN8i3Y.js +0 -1
  369. package/dist/assets/variable-panel-Dd_6lOoR.js +0 -1
  370. /package/dist/assets/{Deferred-BIEvCvJC.js → Deferred-Mppm0cvJ.js} +0 -0
  371. /package/dist/assets/{alert-B2-Y1fzf.js → alert-hjKHAeOD.js} +0 -0
  372. /package/dist/assets/{badge-D5b5ze0K.js → badge-DJuT6BaT.js} +0 -0
  373. /package/dist/assets/{blob-DFrnsWYL.js → blob-CTPcPiam.js} +0 -0
  374. /package/dist/assets/{connection-Cb7zku0y.js → connection-D2GvycR9.js} +0 -0
  375. /package/dist/assets/{copy-BiKQh0sU.js → copy-CkZsxeON.js} +0 -0
  376. /package/dist/assets/{createLucideIcon-Be9UM2Pe.js → createLucideIcon-QLW8E4z5.js} +0 -0
  377. /package/dist/assets/{createReducer-BaSP2BKE.js → createReducer-CFr1RdS2.js} +0 -0
  378. /package/dist/assets/{defaultLocale-DU4zdxes.js → defaultLocale-C6TNIE_k.js} +0 -0
  379. /package/dist/assets/{defaultLocale-BCtmQtCj.js → defaultLocale-DPsgYaXf.js} +0 -0
  380. /package/dist/assets/{dist-DIuPmJ5w.js → dist-Bz53xjA5.js} +0 -0
  381. /package/dist/assets/{dist-BhR4qmIv.js → dist-DcASoeRZ.js} +0 -0
  382. /package/dist/assets/{dist-BMAXVGJe.js → dist-Dlusp3mb.js} +0 -0
  383. /package/dist/assets/{documentation-BZROoSma.js → documentation-B7z6bB-t.js} +0 -0
  384. /package/dist/assets/{emotion-is-prop-valid.esm-plUNooLR.js → emotion-is-prop-valid.esm-BbphD4LX.js} +0 -0
  385. /package/dist/assets/{errors-qtuExmE-.js → errors-_3XAtRr3.js} +0 -0
  386. /package/dist/assets/{es-Hxx5X1vH.js → es-BVCqnQhJ.js} +0 -0
  387. /package/dist/assets/{extends--r5KbeWh.js → extends-Bwhapo2B.js} +0 -0
  388. /package/dist/assets/{fast-deep-equal-DT2Tke28.js → fast-deep-equal-BdzBWnNx.js} +0 -0
  389. /package/dist/assets/{icons-BUUt9FMo.js → icons-CLD-J5J3.js} +0 -0
  390. /package/dist/assets/{kbd-DItNvBdP.js → kbd-BQFiWIjd.js} +0 -0
  391. /package/dist/assets/{main-Co0CqoDt.js → main-CfqcqCNp.js} +0 -0
  392. /package/dist/assets/{marked.esm-BVjBUuHx.js → marked.esm-C_54K2ke.js} +0 -0
  393. /package/dist/assets/{namespace-BstGchRe.js → namespace-CnoeT75h.js} +0 -0
  394. /package/dist/assets/{objectWithoutPropertiesLoose-CGYpiDu4.js → objectWithoutPropertiesLoose-CDpgRi8_.js} +0 -0
  395. /package/dist/assets/{ordinal-DO1z0TEs.js → ordinal-CHS6rGcb.js} +0 -0
  396. /package/dist/assets/{preload-helper-CxnU7XTI.js → preload-helper-DImqtvgl.js} +0 -0
  397. /package/dist/assets/{prop-types-Bv8iPqhZ.js → prop-types-CHKlDUlJ.js} +0 -0
  398. /package/dist/assets/{range-CJAH1fu_.js → range-BPiwmiGf.js} +0 -0
  399. /package/dist/assets/{shim-Bk8nzKPV.js → shim-CWt9rDBn.js} +0 -0
  400. /package/dist/assets/{stex-CETff8Y9.js → stex-BrOrfhKB.js} +0 -0
  401. /package/dist/assets/{strings-1yw0WVap.js → strings-DYBy5ejj.js} +0 -0
  402. /package/dist/assets/{tslib.es6-DItc8Tbq.js → tslib.es6-dlz5WbC8.js} +0 -0
  403. /package/dist/assets/{use-toast-C07-frN_.js → use-toast-D6NNsC80.js} +0 -0
  404. /package/dist/assets/{useEvent-BIiDVnhT.js → useEvent-BOb1a9d1.js} +0 -0
  405. /package/dist/assets/{useLifecycle-Bnvt0QrQ.js → useLifecycle-BfeAlD80.js} +0 -0
  406. /package/dist/assets/{useNonce-Cw4ZAbgi.js → useNonce-BbWkd3B4.js} +0 -0
  407. /package/dist/assets/{useNumberFormatter-DYIEUCTe.js → useNumberFormatter-D21brJ0f.js} +0 -0
  408. /package/dist/assets/{uuid-BWz20PcF.js → uuid-4lb_EYpq.js} +0 -0
@@ -0,0 +1,123 @@
1
+ /* Copyright 2024 Marimo. All rights reserved. */
2
+
3
+ import { afterAll, beforeAll, describe, expect, it } from "vitest";
4
+ import { groupChatsByDate } from "../components/chat/chat-history-utils";
5
+ import type { Chat } from "../core/ai/state";
6
+
7
+ // Mock current time for consistent testing
8
+ const mockNow = new Date("2024-01-15T12:00:00Z").getTime();
9
+
10
+ // Mock Date.now to return our fixed time
11
+ const originalDateNow = Date.now;
12
+ beforeAll(() => {
13
+ Date.now = () => mockNow;
14
+ });
15
+
16
+ afterAll(() => {
17
+ Date.now = originalDateNow;
18
+ });
19
+
20
+ describe("groupChatsByDate", () => {
21
+ const createMockChat = (daysAgo: number, title: string): Chat => ({
22
+ id: `chat-${daysAgo}` as Chat["id"],
23
+ title,
24
+ messages: [],
25
+ createdAt: mockNow - daysAgo * 24 * 60 * 60 * 1000,
26
+ updatedAt: mockNow - daysAgo * 24 * 60 * 60 * 1000,
27
+ });
28
+
29
+ it("should group chats correctly by date periods", () => {
30
+ const chats: Chat[] = [
31
+ createMockChat(0, "Today chat"),
32
+ createMockChat(1, "Yesterday chat"),
33
+ createMockChat(2, "2 days ago chat"),
34
+ createMockChat(3, "3 days ago chat"),
35
+ createMockChat(5, "5 days ago chat"), // Should go to "This week"
36
+ createMockChat(10, "10 days ago chat"), // Should go to "This month"
37
+ createMockChat(40, "40 days ago chat"), // Should go to "Older"
38
+ ];
39
+
40
+ const result = groupChatsByDate(chats);
41
+
42
+ // Should have 7 groups
43
+ expect(result).toHaveLength(chats.length);
44
+
45
+ // Check Today group
46
+ const todayGroup = result.find((g) => g.label === "Today");
47
+ expect(todayGroup?.chats).toHaveLength(1);
48
+ expect(todayGroup?.chats[0].title).toBe("Today chat");
49
+
50
+ // Check Yesterday group
51
+ const yesterdayGroup = result.find((g) => g.label === "Yesterday");
52
+ expect(yesterdayGroup?.chats).toHaveLength(1);
53
+ expect(yesterdayGroup?.chats[0].title).toBe("Yesterday chat");
54
+
55
+ // Check 2d ago group
56
+ const twoDaysGroup = result.find((g) => g.label === "2d ago");
57
+ expect(twoDaysGroup?.chats).toHaveLength(1);
58
+ expect(twoDaysGroup?.chats[0].title).toBe("2 days ago chat");
59
+
60
+ // Check 3d ago group
61
+ const threeDaysGroup = result.find((g) => g.label === "3d ago");
62
+ expect(threeDaysGroup?.chats).toHaveLength(1);
63
+ expect(threeDaysGroup?.chats[0].title).toBe("3 days ago chat");
64
+
65
+ // Check This week group (should include 5)
66
+ const thisWeekGroup = result.find((g) => g.label === "This week");
67
+ expect(thisWeekGroup?.chats).toHaveLength(1);
68
+ expect(thisWeekGroup?.chats.map((c) => c.title)).toContain(
69
+ "5 days ago chat",
70
+ );
71
+
72
+ // Check This month group (should include 40 days ago)
73
+ const thisMonthGroup = result.find((g) => g.label === "This month");
74
+ expect(thisMonthGroup?.chats).toHaveLength(1);
75
+ expect(thisMonthGroup?.chats[0].title).toBe("10 days ago chat");
76
+
77
+ // Check Older group (should include 40 days ago)
78
+ const olderGroup = result.find((g) => g.label === "Older");
79
+ expect(olderGroup?.chats).toHaveLength(1);
80
+ expect(olderGroup?.chats[0].title).toBe("40 days ago chat");
81
+ });
82
+
83
+ it("should include all chats in some group", () => {
84
+ const chats: Chat[] = [
85
+ createMockChat(0, "Today"),
86
+ createMockChat(1, "Yesterday"),
87
+ createMockChat(2, "2 days ago"),
88
+ createMockChat(3, "3 days ago"),
89
+ createMockChat(5, "5 days ago"),
90
+ createMockChat(10, "10 days ago"),
91
+ createMockChat(20, "20 days ago"),
92
+ createMockChat(40, "40 days ago"),
93
+ createMockChat(100, "100 days ago"),
94
+ ];
95
+
96
+ const result = groupChatsByDate(chats);
97
+
98
+ // Count total chats across all groups
99
+ const totalChatsInGroups = result.reduce(
100
+ (sum, group) => sum + group.chats.length,
101
+ 0,
102
+ );
103
+ expect(totalChatsInGroups).toBe(chats.length);
104
+ });
105
+
106
+ it("should handle empty chat list", () => {
107
+ const result = groupChatsByDate([]);
108
+ expect(result).toHaveLength(0);
109
+ });
110
+
111
+ it("should filter out empty groups", () => {
112
+ const chats: Chat[] = [
113
+ createMockChat(0, "Today chat"),
114
+ createMockChat(40, "Old chat"),
115
+ ];
116
+
117
+ const result = groupChatsByDate(chats);
118
+
119
+ // Should only have Today and Older groups, not the empty ones in between
120
+ expect(result).toHaveLength(2);
121
+ expect(result.map((g) => g.label)).toEqual(["Today", "Older"]);
122
+ });
123
+ });
@@ -930,6 +930,29 @@ export const AiAssistConfig: React.FC<AiConfigProps> = ({
930
930
  return (
931
931
  <SettingGroup>
932
932
  <SettingSubtitle>AI Assistant</SettingSubtitle>
933
+
934
+ <FormField
935
+ control={form.control}
936
+ name="ai.inline_tooltip"
937
+ render={({ field }) => (
938
+ <div className="flex flex-col gap-y-1">
939
+ <FormItem className={formItemClasses}>
940
+ <FormLabel className="font-normal">AI Edit Tooltip</FormLabel>
941
+ <FormControl>
942
+ <Checkbox
943
+ data-testid="inline-ai-checkbox"
944
+ checked={field.value === true}
945
+ onCheckedChange={field.onChange}
946
+ />
947
+ </FormControl>
948
+ </FormItem>
949
+ <FormDescription>
950
+ Enable "Edit with AI" tooltip when selecting code.
951
+ </FormDescription>
952
+ </div>
953
+ )}
954
+ />
955
+
933
956
  <FormErrorsBanner />
934
957
  <ModelSelector
935
958
  label="Chat Model"
@@ -1,6 +1,6 @@
1
1
  /* Copyright 2024 Marimo. All rights reserved. */
2
2
 
3
- import { CheckSquareIcon } from "lucide-react";
3
+ import { CheckSquareIcon, Loader2, RefreshCwIcon } from "lucide-react";
4
4
  import React from "react";
5
5
  import type { UseFormReturn } from "react-hook-form";
6
6
  import {
@@ -12,6 +12,8 @@ import {
12
12
  } from "@/components/ui/card";
13
13
  import { FormField, FormItem } from "@/components/ui/form";
14
14
  import type { UserConfig } from "@/core/config/config-schema";
15
+ import { useMCPRefresh, useMCPStatus } from "../mcp/hooks";
16
+ import { McpStatusText } from "../mcp/mcp-status-indicator";
15
17
  import { Button } from "../ui/button";
16
18
  import { Kbd } from "../ui/kbd";
17
19
  import { SettingSubtitle } from "./common";
@@ -45,10 +47,48 @@ const PRESET_CONFIGS: PresetConfig[] = [
45
47
 
46
48
  export const MCPConfig: React.FC<MCPConfigProps> = ({ form, onSubmit }) => {
47
49
  const { handleClick } = useOpenSettingsToTab();
50
+ const { data: status, refetch, isFetching } = useMCPStatus();
51
+ const { refresh, isRefreshing } = useMCPRefresh();
52
+
53
+ const handleRefresh = async () => {
54
+ await refresh();
55
+ refetch();
56
+ };
48
57
 
49
58
  return (
50
59
  <div className="flex flex-col gap-4">
51
- <SettingSubtitle>MCP Servers</SettingSubtitle>
60
+ <div className="flex items-center justify-between">
61
+ <SettingSubtitle>MCP Servers</SettingSubtitle>
62
+ <div className="flex items-center gap-2">
63
+ {status && <McpStatusText status={status.status} />}
64
+ <Button
65
+ variant="outline"
66
+ size="xs"
67
+ onClick={handleRefresh}
68
+ disabled={isRefreshing || isFetching}
69
+ >
70
+ {isRefreshing || isFetching ? (
71
+ <Loader2 className="h-3 w-3 animate-spin" />
72
+ ) : (
73
+ <RefreshCwIcon className="h-3 w-3" />
74
+ )}
75
+ </Button>
76
+ </div>
77
+ </div>
78
+ {status?.error && (
79
+ <div className="text-xs text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-950/20 p-2 rounded">
80
+ {status.error}
81
+ </div>
82
+ )}
83
+ {status?.servers && (
84
+ <div className="text-xs text-muted-foreground">
85
+ {Object.entries(status.servers).map(([server, status]) => (
86
+ <div key={server}>
87
+ {server}: <McpStatusText status={status} />
88
+ </div>
89
+ ))}
90
+ </div>
91
+ )}
52
92
  <p className="text-sm text-muted-foreground">
53
93
  Enable Model Context Protocol (MCP) servers to provide additional
54
94
  capabilities and data sources for AI features.
@@ -1228,30 +1228,6 @@ export const UserConfigForm: React.FC = () => {
1228
1228
  notebook to take effect.
1229
1229
  </p>
1230
1230
 
1231
- <FormField
1232
- control={form.control}
1233
- name="experimental.inline_ai_tooltip"
1234
- render={({ field }) => (
1235
- <div className="flex flex-col gap-y-1">
1236
- <FormItem className={formItemClasses}>
1237
- <FormLabel className="font-normal">
1238
- AI Edit Tooltip
1239
- </FormLabel>
1240
- <FormControl>
1241
- <Checkbox
1242
- data-testid="inline-ai-checkbox"
1243
- checked={field.value === true}
1244
- onCheckedChange={field.onChange}
1245
- />
1246
- </FormControl>
1247
- </FormItem>
1248
- <FormDescription>
1249
- Enable experimental "Edit with AI" tooltip when selecting
1250
- code.
1251
- </FormDescription>
1252
- </div>
1253
- )}
1254
- />
1255
1231
  <FormField
1256
1232
  control={form.control}
1257
1233
  name="experimental.rtc_v2"
@@ -133,7 +133,7 @@ describe("parseContextFromPrompt", () => {
133
133
  type: "resource",
134
134
  resource: {
135
135
  uri: "context.md",
136
- mimeType: "text/markdown",
136
+ mimeType: "text/plain",
137
137
  text: "formatted context",
138
138
  },
139
139
  });
@@ -867,7 +867,7 @@ const AgentPanel: React.FC = () => {
867
867
  type: "resource",
868
868
  resource: {
869
869
  uri: "marimo_rules.md",
870
- mimeType: "text/markdown",
870
+ mimeType: "text/plain",
871
871
  text: getAgentPrompt(filename),
872
872
  },
873
873
  },
@@ -30,7 +30,6 @@ import {
30
30
  } from "@/components/ui/popover";
31
31
  import { logNever } from "@/utils/assertNever";
32
32
  import { cn } from "@/utils/cn";
33
- import { type Base64String, base64ToDataURL } from "@/utils/json/base64";
34
33
  import { Strings } from "@/utils/strings";
35
34
  import { MarkdownRenderer } from "../markdown-renderer";
36
35
  import { SimpleAccordion } from "./common";
@@ -289,7 +288,7 @@ export const PlansBlock = (props: { data: PlanNotificationEvent[] }) => {
289
288
 
290
289
  export const UserMessagesBlock = (props: { data: UserNotificationEvent[] }) => {
291
290
  return (
292
- <div className="flex flex-col gap-2 text-muted-foreground border p-2 bg-background rounded break-words">
291
+ <div className="flex flex-col gap-2 text-muted-foreground border p-2 bg-background rounded break-words overflow-x-hidden">
293
292
  <ContentBlocks data={props.data.map((item) => item.content)} />
294
293
  </div>
295
294
  );
@@ -364,58 +363,28 @@ export const ResourceBlock = (props: { data: ContentBlockOf<"resource"> }) => {
364
363
  return (
365
364
  <Popover>
366
365
  <PopoverTrigger>
367
- <span className="flex items-center gap-1">
366
+ <span className="flex items-center gap-1 hover:bg-muted rounded-md px-1">
368
367
  {props.data.resource.mimeType && (
369
368
  <MimeIcon mimeType={props.data.resource.mimeType} />
370
369
  )}
371
370
  {props.data.resource.uri}
372
371
  </span>
373
372
  </PopoverTrigger>
374
- <PopoverContent className="max-h-96 overflow-y-auto scrollbar-thin">
375
- <MarkdownRenderer content={props.data.resource.text} />
373
+ <PopoverContent className="max-h-96 overflow-y-auto scrollbar-thin whitespace-pre-wrap w-full max-w-[500px]">
374
+ <span className="text-muted-foreground text-xs mb-1 italic">
375
+ Formatted for agents, not humans.
376
+ </span>
377
+ {props.data.resource.mimeType === "text/plain" ? (
378
+ <pre className="text-xs whitespace-pre-wrap p-2 bg-muted rounded-md break-words">
379
+ {props.data.resource.text}
380
+ </pre>
381
+ ) : (
382
+ <MarkdownRenderer content={props.data.resource.text} />
383
+ )}
376
384
  </PopoverContent>
377
385
  </Popover>
378
386
  );
379
387
  }
380
-
381
- if ("blob" in props.data.resource) {
382
- if (props.data.resource.mimeType?.startsWith("image/")) {
383
- return (
384
- <ImageBlock
385
- data={{
386
- type: "image",
387
- mimeType: props.data.resource.mimeType,
388
- data: props.data.resource.blob,
389
- }}
390
- />
391
- );
392
- }
393
- if (props.data.resource.mimeType?.startsWith("audio/")) {
394
- return (
395
- <AudioBlock
396
- data={{
397
- type: "audio",
398
- mimeType: props.data.resource.mimeType,
399
- data: props.data.resource.blob,
400
- }}
401
- />
402
- );
403
- }
404
- const dataURL = base64ToDataURL(
405
- props.data.resource.blob as Base64String,
406
- props.data.resource.mimeType ?? "",
407
- );
408
- return (
409
- <a href={dataURL} className="flex items-center gap-1" download={true}>
410
- {props.data.resource.mimeType && (
411
- <MimeIcon mimeType={props.data.resource.mimeType} />
412
- )}
413
- {props.data.resource.uri}
414
- </a>
415
- );
416
- }
417
- logNever(props.data.resource);
418
- return null;
419
388
  };
420
389
 
421
390
  export const ResourceLinkBlock = (props: {
@@ -427,15 +396,38 @@ export const ResourceLinkBlock = (props: {
427
396
  href={props.data.uri}
428
397
  target="_blank"
429
398
  rel="noopener noreferrer"
430
- className="text-link hover:underline"
399
+ className="text-link hover:underline px-1"
431
400
  >
432
401
  {props.data.name}
433
402
  </a>
434
403
  );
435
404
  }
436
405
 
406
+ // Show image in popover for image mime types
407
+ if (props.data.mimeType?.startsWith("image/")) {
408
+ return (
409
+ <div>
410
+ <Popover>
411
+ <PopoverTrigger>
412
+ <span className="flex items-center gap-1 hover:bg-muted rounded-md px-1 cursor-pointer">
413
+ <MimeIcon mimeType={props.data.mimeType} />
414
+ {props.data.name || props.data.title || props.data.uri}
415
+ </span>
416
+ </PopoverTrigger>
417
+ <PopoverContent className="w-auto max-w-[500px] p-2">
418
+ <img
419
+ src={props.data.uri}
420
+ alt={props.data.name || props.data.title || "Image"}
421
+ className="max-w-full max-h-96 object-contain"
422
+ />
423
+ </PopoverContent>
424
+ </Popover>
425
+ </div>
426
+ );
427
+ }
428
+
437
429
  return (
438
- <span className="flex items-center gap-1">
430
+ <span className="flex items-center gap-1 px-1">
439
431
  {props.data.mimeType && <MimeIcon mimeType={props.data.mimeType} />}
440
432
  {props.data.name || props.data.title || props.data.uri}
441
433
  </span>
@@ -443,22 +435,23 @@ export const ResourceLinkBlock = (props: {
443
435
  };
444
436
 
445
437
  export const MimeIcon = (props: { mimeType: string }) => {
438
+ const classNames = "h-2 w-2 flex-shrink-0";
446
439
  if (props.mimeType.startsWith("image/")) {
447
- return <FileImageIcon className="h-2 w-2" />;
440
+ return <FileImageIcon className={classNames} />;
448
441
  }
449
442
  if (props.mimeType.startsWith("audio/")) {
450
- return <FileAudio2Icon className="h-2 w-2" />;
443
+ return <FileAudio2Icon className={classNames} />;
451
444
  }
452
445
  if (props.mimeType.startsWith("video/")) {
453
- return <FileVideoCameraIcon className="h-2 w-2" />;
446
+ return <FileVideoCameraIcon className={classNames} />;
454
447
  }
455
448
  if (props.mimeType.startsWith("text/")) {
456
- return <FileTextIcon className="h-2 w-2" />;
449
+ return <FileTextIcon className={classNames} />;
457
450
  }
458
451
  if (props.mimeType.startsWith("application/")) {
459
- return <FileJsonIcon className="h-2 w-2" />;
452
+ return <FileJsonIcon className={classNames} />;
460
453
  }
461
- return <FileIcon className="h-2 w-2" />;
454
+ return <FileIcon className={classNames} />;
462
455
  };
463
456
 
464
457
  export const SessionNotificationsBlock = <
@@ -533,7 +526,7 @@ export const ToolNotificationsBlock = (props: {
533
526
  const toolCalls = mergeToolCalls(props.data);
534
527
 
535
528
  return (
536
- <div className="flex flex-col text-muted-foreground">
529
+ <div className="flex flex-col text-muted-foreground overflow-x-hidden">
537
530
  {toolCalls.map((item) => (
538
531
  <SimpleAccordion
539
532
  key={item.toolCallId}
@@ -68,7 +68,7 @@ export const SimpleAccordion: React.FC<SimpleAccordionProps> = ({
68
68
  >
69
69
  <span className="flex items-center gap-1">
70
70
  {getStatusIcon()}
71
- <code className="font-mono text-xs">{title}</code>
71
+ <code className="font-mono text-xs truncate">{title}</code>
72
72
  </span>
73
73
  </AccordionTrigger>
74
74
  <AccordionContent className="p-2">
@@ -93,7 +93,7 @@ export async function parseContextFromPrompt(
93
93
  type: "resource",
94
94
  resource: {
95
95
  uri: "context.md",
96
- mimeType: "text/markdown",
96
+ mimeType: "text/plain",
97
97
  text: contextString,
98
98
  },
99
99
  });
@@ -30,7 +30,7 @@ const SessionTab: React.FC<SessionTabProps> = memo(
30
30
  <div
31
31
  className={cn(
32
32
  "flex items-center gap-1 px-2 py-1 text-xs border-r border-border bg-muted/30 hover:bg-muted/50 cursor-pointer min-w-0",
33
- isActive && "bg-background border-b-0 relative z-10",
33
+ isActive && "bg-background border-b-0 relative z-1",
34
34
  )}
35
35
  onClick={() => onSelect(session.tabId)}
36
36
  >
@@ -0,0 +1,125 @@
1
+ /* Copyright 2024 Marimo. All rights reserved. */
2
+
3
+ import { useAtomValue } from "jotai";
4
+ import { BotMessageSquareIcon, ClockIcon, SearchIcon } from "lucide-react";
5
+ import { useMemo, useState } from "react";
6
+ import { useLocale } from "react-aria";
7
+ import { Button } from "@/components/ui/button";
8
+ import { Input } from "@/components/ui/input";
9
+ import {
10
+ Popover,
11
+ PopoverContent,
12
+ PopoverTrigger,
13
+ } from "@/components/ui/popover";
14
+ import { ScrollArea } from "@/components/ui/scroll-area";
15
+ import { Tooltip } from "@/components/ui/tooltip";
16
+ import { type ChatId, chatStateAtom } from "@/core/ai/state";
17
+ import { cn } from "@/utils/cn";
18
+ import { timeAgo } from "@/utils/dates";
19
+ import { PanelEmptyState } from "../editor/chrome/panels/empty-state";
20
+ import { groupChatsByDate } from "./chat-history-utils";
21
+
22
+ interface ChatHistoryPopoverProps {
23
+ activeChatId: ChatId | undefined;
24
+ setActiveChat: (id: ChatId | null) => void;
25
+ }
26
+
27
+ export const ChatHistoryPopover: React.FC<ChatHistoryPopoverProps> = ({
28
+ activeChatId,
29
+ setActiveChat,
30
+ }) => {
31
+ const chatState = useAtomValue(chatStateAtom);
32
+ const { locale } = useLocale();
33
+ const [searchQuery, setSearchQuery] = useState("");
34
+
35
+ const chats = useMemo(() => {
36
+ return [...chatState.chats.values()].sort(
37
+ (a, b) => b.updatedAt - a.updatedAt,
38
+ );
39
+ }, [chatState.chats]);
40
+
41
+ const filteredChats = useMemo(() => {
42
+ if (!searchQuery.trim()) {
43
+ return chats;
44
+ }
45
+ return chats.filter((chat) =>
46
+ chat.title.toLowerCase().includes(searchQuery.toLowerCase()),
47
+ );
48
+ }, [chats, searchQuery]);
49
+
50
+ const groupedChats = useMemo(() => {
51
+ return groupChatsByDate(filteredChats);
52
+ }, [filteredChats]);
53
+
54
+ return (
55
+ <Popover>
56
+ <Tooltip content="Previous chats">
57
+ <PopoverTrigger asChild={true}>
58
+ <Button variant="text" size="icon">
59
+ <ClockIcon className="h-4 w-4" />
60
+ </Button>
61
+ </PopoverTrigger>
62
+ </Tooltip>
63
+ <PopoverContent className="w-[480px] p-0" align="start" side="right">
64
+ <div className="pt-3 px-3 w-full">
65
+ <Input
66
+ placeholder="Search chat history..."
67
+ value={searchQuery}
68
+ onChange={(e) => setSearchQuery(e.target.value)}
69
+ className="text-xs"
70
+ />
71
+ </div>
72
+ <ScrollArea className="h-[450px] p-2">
73
+ <div className="space-y-3">
74
+ {chats.length === 0 && (
75
+ <PanelEmptyState
76
+ title="No chats yet"
77
+ description="Start a new chat to get started"
78
+ icon={<BotMessageSquareIcon />}
79
+ />
80
+ )}
81
+ {filteredChats.length === 0 && searchQuery && chats.length > 0 && (
82
+ <PanelEmptyState
83
+ title="No chats found"
84
+ description={`No chats match "${searchQuery}"`}
85
+ icon={<SearchIcon />}
86
+ />
87
+ )}
88
+ {groupedChats.map((group, idx) => (
89
+ <div key={group.label} className="space-y-2">
90
+ <div className="text-xs px-1 text-muted-foreground/60">
91
+ {group.label}
92
+ </div>
93
+ <div>
94
+ {group.chats.map((chat) => (
95
+ <button
96
+ key={chat.id}
97
+ className={cn(
98
+ "w-full p-1 rounded-md cursor-pointer text-left flex items-center justify-between",
99
+ chat.id === activeChatId && "bg-accent",
100
+ chat.id !== activeChatId && "hover:bg-muted/20",
101
+ )}
102
+ onClick={() => {
103
+ setActiveChat(chat.id);
104
+ }}
105
+ type="button"
106
+ >
107
+ <div className="flex-1 min-w-0">
108
+ <div className="text-sm truncate">{chat.title}</div>
109
+ </div>
110
+ <div className="text-xs text-muted-foreground/60 ml-2 flex-shrink-0">
111
+ {timeAgo(chat.updatedAt, locale)}
112
+ </div>
113
+ </button>
114
+ ))}
115
+ </div>
116
+ {/* If last group, don't show a divider */}
117
+ {idx !== groupedChats.length - 1 && <hr />}
118
+ </div>
119
+ ))}
120
+ </div>
121
+ </ScrollArea>
122
+ </PopoverContent>
123
+ </Popover>
124
+ );
125
+ };
@@ -0,0 +1,69 @@
1
+ /* Copyright 2024 Marimo. All rights reserved. */
2
+
3
+ import type { Chat } from "@/core/ai/state";
4
+
5
+ const DATE_GROUP_CONFIG = [
6
+ { label: "Today", days: 0 },
7
+ { label: "Yesterday", days: 1 },
8
+ { label: "2d ago", days: 2 },
9
+ { label: "3d ago", days: 3 },
10
+ { label: "This week", days: 7 },
11
+ { label: "This month", days: 30 },
12
+ ] as const;
13
+
14
+ interface DateGroup {
15
+ label: string;
16
+ days: number;
17
+ chats: Chat[];
18
+ }
19
+
20
+ // Utility function to group chats by date periods
21
+ export const groupChatsByDate = (chats: Chat[]): DateGroup[] => {
22
+ const now = Date.now();
23
+ const oneDayMs = 24 * 60 * 60 * 1000;
24
+
25
+ // Initialize groups with empty chat arrays
26
+ const groups: DateGroup[] = DATE_GROUP_CONFIG.map((config) => ({
27
+ ...config,
28
+ chats: [],
29
+ }));
30
+
31
+ const olderGroup: DateGroup = {
32
+ label: "Older",
33
+ days: Infinity,
34
+ chats: [],
35
+ };
36
+
37
+ // Helper function to determine which group a chat belongs to
38
+ const getGroupForChat = (daysDiff: number): DateGroup => {
39
+ // Use switch for exact day matches, then handle ranges
40
+ switch (daysDiff) {
41
+ case 0:
42
+ return groups[0]; // Today
43
+ case 1:
44
+ return groups[1]; // Yesterday
45
+ case 2:
46
+ return groups[2]; // 2d ago
47
+ case 3:
48
+ return groups[3]; // 3d ago
49
+ default:
50
+ // Handle range-based grouping for older chats
51
+ if (daysDiff >= 4 && daysDiff <= 7) {
52
+ return groups[4]; // This week
53
+ } else if (daysDiff >= 8 && daysDiff <= 30) {
54
+ return groups[5]; // This month
55
+ }
56
+ // Everything else goes to Older
57
+ return olderGroup;
58
+ }
59
+ };
60
+
61
+ for (const chat of chats) {
62
+ const daysDiff = Math.floor((now - chat.updatedAt) / oneDayMs);
63
+ const targetGroup = getGroupForChat(daysDiff);
64
+ targetGroup.chats.push(chat);
65
+ }
66
+
67
+ // Return only non-empty groups
68
+ return [...groups, olderGroup].filter((group) => group.chats.length > 0);
69
+ };